diff --git a/Pipfile b/Pipfile new file mode 100644 index 000000000..03b834648 --- /dev/null +++ b/Pipfile @@ -0,0 +1,14 @@ +[[source]] +url = "https://pypi.org/simple" +verify_ssl = true +name = "pypi" + +[dev-packages] + +[packages] +llbase = "*" +certifi = "*" +autobuild = {hg = "https://bitbucket.org/alchemyviewer/autobuild-1.1"} + +[requires] +python_version = "2.7" diff --git a/autobuild.xml b/autobuild.xml index 8df1b9a15..c3841bd8b 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -68,18 +68,18 @@ archive hash - b95e484e5b6cc0d10da48d3cf0ad37cd + b82d5aa8380926240f3415279480c831 hash_algorithm md5 url - http://depot.alchemyviewer.org/pub/packages/common/abseil_cpp-20190327.190862343-common-190862343.tar.bz2 + https://pkg.alchemyviewer.org/repository/autobuild-external/abseil-cpp/common/abseil_cpp-ac78ffc.1-common-1.tar.bz2 name common version - 20190327.190862343 + ac78ffc.1 apr_suite @@ -650,11 +650,11 @@ archive hash - 2f44b376e436f37cbad5c7567edddebd + 06746b78827e9a0c6b666bd2528d36ad hash_algorithm md5 url - https://bitbucket.org/router_gray/rg_3p-dullahan/downloads/dullahan-1.1.1085-3.3497.1833.g13f506f-linux64-201902042123.tar.bz2 + https://bitbucket.org/SingularityViewer/libraries/downloads/dullahan-1.1.1320_73.1.12%252Bgee4b49f%252Bchromium-73.0.3683.75-linux64-192030536.tar.bz2 name linux64 @@ -664,9 +664,9 @@ archive hash - c3e093d40e93ff242e9b9c953ae7316c + e19b664ad8cf9e7f4a7bf649d28faa76 url - https://depot.alchemyviewer.org/pub/windows/lib-vc142/dullahan-1.1.930-3.3282.1733.g9091548-windows-201802202358.tar.bz2 + https://bitbucket.org/SingularityViewer/libraries/downloads/dullahan-1.1.1320_73.1.12+gee4b49f+chromium-73.0.3683.75-windows-191102212.tar.bz2 name windows @@ -802,7 +802,7 @@ fmodstudio copyright - FMOD Studio, copyright (c) Firelight Technologies Pty, Ltd., 2012-2017. + FMOD Studio, copyright (c) Firelight Technologies Pty, Ltd., 2012-2019. description FMOD Studio audio system library license @@ -818,15 +818,29 @@ archive hash - a3ccf7916d1e0b6f01370978b661c139 + 4a4e1bfd0e1e982643e75533ead10c55 hash_algorithm md5 url - https://depot.alchemyviewer.org/pub/darwin/lib/fmodstudio-1.10.02-darwin-201712262058.tar.bz2 + https://pkg.alchemyviewer.org/repository/autobuild-internal/fmodstudio/darwin/fmodstudio-2.00.03.192211300-darwin-192211300.tar.bz2 name darwin + darwin64 + + archive + + hash + fe1a606582fb72d5d1c9ec4a2d906830 + hash_algorithm + md5 + url + https://pkg.alchemyviewer.org/repository/autobuild-internal/fmodstudio/darwin64/fmodstudio-2.00.03.192211302-darwin64-192211302.tar.bz2 + + name + darwin64 + linux archive @@ -836,7 +850,7 @@ hash_algorithm md5 url - http://depot.alchemyviewer.org/pub/linux/lib/fmodstudio-1.06.07-linux-201507231333.tar.bz2 + https://depot.alchemyviewer.org/pub/linux/lib/fmodstudio-1.06.07-linux-201507231333.tar.bz2 name linux @@ -850,7 +864,7 @@ hash_algorithm md5 url - https://depot.alchemyviewer.org/pub/linux64/lib/fmodstudio-1.10.00-linux64-201709282320.tar.bz2 + /opt/devel/secondlife/pkg/fmodstudio-2.00.02.191991250-linux64-191991250.tar.bz2 name linux64 @@ -860,11 +874,11 @@ archive hash - b23a30967666da49346983658ed50e92 + e0e87e0423fa42e4d2997b47b92eac6e hash_algorithm md5 url - https://depot.alchemyviewer.org/pub/windows/lib/fmodstudio-1.10.00-windows-201709290225.tar.bz2 + https://pkg.alchemyviewer.org/repository/autobuild-internal/fmodstudio/windows/fmodstudio-2.00.03.192211030-windows-192211030.tar.bz2 name windows @@ -874,11 +888,11 @@ archive hash - 779ae33c6b84656295bd6cf50a69c830 + c2e55e1bfef7e066a0e40867a64b4cce hash_algorithm md5 url - http://depot.alchemyviewer.org/pub/packages/windows64/msvc/fmodstudio-1.10.10.190360453-windows64-190360453.tar.bz2 + https://pkg.alchemyviewer.org/repository/autobuild-internal/fmodstudio/windows64/fmodstudio-2.00.03.192211029-windows64-192211029.tar.bz2 name windows64 @@ -2106,7 +2120,7 @@ nvapi copyright - Copyright (c) 2007- 2014 NVIDIA Corporation. All rights reserved. + Copyright (c) 2007- 2019 NVIDIA Corporation. All rights reserved. license nvapi license_file @@ -2120,11 +2134,11 @@ archive hash - f70cc94b1f43c4889b0dfff33f40fb11 + 408eff309f6f3031d74da5491c1852a9 hash_algorithm md5 url - file:///c:/devel/secondlife/packages/windows/nvapi-R361v2-windows-201604020339.tar.bz2 + https://pkg.alchemyviewer.org/repository/autobuild-internal/nvapi/windows/nvapi-R430.192211828-windows-192211828.tar.bz2 name windows @@ -2134,18 +2148,18 @@ archive hash - 619598988143e12ad0d1a271f881b3bd + 76a547f558b8499dc85135b8718eb18a hash_algorithm md5 url - file:///c:/devel/secondlife/packages/windows64/nvapi-R384-windows64-201712260642.tar.bz2 + https://pkg.alchemyviewer.org/repository/autobuild-internal/nvapi/windows64/nvapi-R430.192211828-windows64-192211828.tar.bz2 name windows64 version - R384 + R430.192211828 ogg_vorbis @@ -3121,7 +3135,7 @@ windows build_directory - build-vc$AUTOBUILD_WIN_VSVER-$AUTOBUILD_ADDRSIZE + build-vc${AUTOBUILD_WIN_VSVER|161}-$AUTOBUILD_ADDRSIZE configurations RelWithDebInfo diff --git a/indra/CMakeLists.txt b/indra/CMakeLists.txt index b480c96b3..ab77f9e96 100644 --- a/indra/CMakeLists.txt +++ b/indra/CMakeLists.txt @@ -17,6 +17,7 @@ project(${ROOT_PROJECT_NAME}) set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") include(Variables) +include(00-Common) include(BuildVersion) set(CMAKE_CXX_STANDARD 14) @@ -27,6 +28,9 @@ if (NOT CMAKE_BUILD_TYPE) "Build type. One of: Debug Release RelWithDebInfo" FORCE) endif (NOT CMAKE_BUILD_TYPE) +include(Abseil-CPP) +# Dependencies +add_subdirectory(${ABSEIL_SRC_DIR} ${ABSEIL_BIN_DIR}) add_subdirectory(cmake) add_subdirectory(${LIBS_OPEN_PREFIX}aistatemachine) add_subdirectory(${LIBS_OPEN_PREFIX}llaudio) diff --git a/indra/aistatemachine/CMakeLists.txt b/indra/aistatemachine/CMakeLists.txt index 791ff9d25..42cfec5e2 100644 --- a/indra/aistatemachine/CMakeLists.txt +++ b/indra/aistatemachine/CMakeLists.txt @@ -39,3 +39,9 @@ set_source_files_properties(${aistatemachine_HEADER_FILES} list(APPEND aistatemachine_SOURCE_FILES ${aistatemachine_HEADER_FILES}) add_library (aistatemachine ${aistatemachine_SOURCE_FILES}) + +target_link_libraries( + aistatemachine + PUBLIC + llcommon + ) diff --git a/indra/cmake/Abseil-CPP.cmake b/indra/cmake/Abseil-CPP.cmake new file mode 100644 index 000000000..c7bb0f763 --- /dev/null +++ b/indra/cmake/Abseil-CPP.cmake @@ -0,0 +1,8 @@ +# -*- cmake -*- +include(Prebuilt) + +set(BUILD_TESTING OFF) +use_prebuilt_binary(abseil-cpp) +set(ABSEIL_SRC_DIR ${LIBS_PREBUILT_DIR}/abseil-cpp) +set(ABSEIL_BIN_DIR ${CMAKE_BINARY_DIR}/abseil-cpp) + diff --git a/indra/cmake/CEFPlugin.cmake b/indra/cmake/CEFPlugin.cmake index f19e38254..7f90e6afa 100644 --- a/indra/cmake/CEFPlugin.cmake +++ b/indra/cmake/CEFPlugin.cmake @@ -39,7 +39,7 @@ elseif (DARWIN) elseif (LINUX) set(CEF_PLUGIN_LIBRARIES dullahan - cef_dll_wrapper + cef_dll_wrapper.a cef ) endif (WINDOWS) diff --git a/indra/cmake/CMakeLists.txt b/indra/cmake/CMakeLists.txt index 0889c38d0..04ae8dc00 100644 --- a/indra/cmake/CMakeLists.txt +++ b/indra/cmake/CMakeLists.txt @@ -8,6 +8,7 @@ set(cmake_SOURCE_FILES CMakeLists.txt 00-Common.cmake + Abseil-CPP.cmake AIStateMachine.cmake APR.cmake Audio.cmake @@ -38,7 +39,6 @@ set(cmake_SOURCE_FILES FindNDOF.cmake FindOpenJPEG.cmake FindTut.cmake - FindVCRedist.cmake FindURIPARSER.cmake FindXmlRpcEpi.cmake FMODSTUDIO.cmake diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake index fada12e96..b9d12919b 100644 --- a/indra/cmake/Copy3rdPartyLibs.cmake +++ b/indra/cmake/Copy3rdPartyLibs.cmake @@ -13,6 +13,10 @@ include(LLCommon) # set up platform specific lists of files that need to be copied ################################################################### if(WINDOWS) + set(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_SKIP TRUE) + set(CMAKE_INSTALL_UCRT_LIBRARIES TRUE) + include(InstallRequiredSystemLibrariesAL) + set(SHARED_LIB_STAGING_DIR_DEBUG "${SHARED_LIB_STAGING_DIR}/Debug") set(SHARED_LIB_STAGING_DIR_RELWITHDEBINFO "${SHARED_LIB_STAGING_DIR}/RelWithDebInfo") set(SHARED_LIB_STAGING_DIR_RELEASE "${SHARED_LIB_STAGING_DIR}/Release") @@ -83,15 +87,30 @@ if(WINDOWS) endif(NOT DISABLE_TCMALLOC) if (FMODSTUDIO) - if(ADDRESS_SIZE STREQUAL 64) - set(debug_files ${debug_files} fmodL64.dll) - set(release_files ${release_files} fmod64.dll) - else(ADDRESS_SIZE STREQUAL 64) - set(debug_files ${debug_files} fmodL.dll) - set(release_files ${release_files} fmod.dll) - endif(ADDRESS_SIZE STREQUAL 64) + set(debug_files ${debug_files} fmodL.dll) + set(release_files ${release_files} fmod.dll) endif (FMODSTUDIO) + foreach(redistfullfile IN LISTS CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS) + get_filename_component(redistfilepath ${redistfullfile} DIRECTORY ) + get_filename_component(redistfilename ${redistfullfile} NAME) + copy_if_different( + ${redistfilepath} + "${SHARED_LIB_STAGING_DIR_RELEASE}" + out_targets + ${redistfilename} + ) + set(third_party_targets ${third_party_targets} ${out_targets}) + + copy_if_different( + ${redistfilepath} + "${SHARED_LIB_STAGING_DIR_RELWITHDEBINFO}" + out_targets + ${redistfilename} + ) + set(third_party_targets ${third_party_targets} ${out_targets}) + endforeach() + elseif(DARWIN) set(SHARED_LIB_STAGING_DIR_DEBUG "${SHARED_LIB_STAGING_DIR}/Debug/Resources") set(SHARED_LIB_STAGING_DIR_RELWITHDEBINFO "${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/Resources") diff --git a/indra/cmake/FMODSTUDIO.cmake b/indra/cmake/FMODSTUDIO.cmake index 8d8e796c1..84de5689e 100644 --- a/indra/cmake/FMODSTUDIO.cmake +++ b/indra/cmake/FMODSTUDIO.cmake @@ -11,13 +11,8 @@ if (FMODSTUDIO) set(lib_suffix .so) endif(WINDOWS) if(WINDOWS) - if(WORD_SIZE EQUAL 64) - set(FMOD_LIBRARY_RELEASE ${LIBS_PREBUILT_DIR}/lib/release/fmod64${lib_suffix}) - set(FMOD_LIBRARY_DEBUG ${LIBS_PREBUILT_DIR}/lib/debug/fmodL64${lib_suffix}) - else(WORD_SIZE EQUAL 64) - set(FMOD_LIBRARY_RELEASE ${LIBS_PREBUILT_DIR}/lib/release/fmod${lib_suffix}) - set(FMOD_LIBRARY_DEBUG ${LIBS_PREBUILT_DIR}/lib/debug/fmodL${lib_suffix}) - endif(WORD_SIZE EQUAL 64) + set(FMOD_LIBRARY_RELEASE ${LIBS_PREBUILT_DIR}/lib/release/fmod${lib_suffix}) + set(FMOD_LIBRARY_DEBUG ${LIBS_PREBUILT_DIR}/lib/debug/fmodL${lib_suffix}) else(WINDOWS) set(FMOD_LIBRARY_RELEASE ${LIBS_PREBUILT_DIR}/lib/release/libfmod${lib_suffix}) set(FMOD_LIBRARY_DEBUG ${LIBS_PREBUILT_DIR}/lib/debug/libfmodL${lib_suffix}) diff --git a/indra/cmake/FindVCRedist.cmake b/indra/cmake/FindVCRedist.cmake deleted file mode 100644 index c2cda59cd..000000000 --- a/indra/cmake/FindVCRedist.cmake +++ /dev/null @@ -1,34 +0,0 @@ -include(Variables) - -if(WINDOWS) - if(MSVC_VERSION GREATER_EQUAL 1919 AND MSVC_VERSION LESS 1920) - set(VISUAL_STUDIO_VERSION 15.0) - set(VISUAL_STUDIO_VERSION_UPPER 16.0) - elseif(MSVC_VERSION GREATER_EQUAL 1920 AND MSVC_VERSION LESS 1940) - set(VISUAL_STUDIO_VERSION 16.0) - set(VISUAL_STUDIO_VERSION_UPPER 17.0) - endif () - - set(vswhere "$ENV{PROGRAMFILES\(X86\)}\\Microsoft Visual Studio\\Installer\\vswhere.exe") - if(EXISTS ${vswhere}) - execute_process(COMMAND ${vswhere} -version "[${VISUAL_STUDIO_VERSION},${VISUAL_STUDIO_VERSION_UPPER})" -property "installationPath" - OUTPUT_VARIABLE installationPath - OUTPUT_STRIP_TRAILING_WHITESPACE) - file(TO_CMAKE_PATH ${installationPath} installationPath) - set(redistPath "${installationPath}/VC/Redist/MSVC") - file(GLOB redistPath "${installationPath}/VC/Redist/MSVC/*") - list(LENGTH redistPath length) - if(length EQUAL 1) - if(ADDRESS_SIZE EQUAL 64) - set(VISUAL_STUDIO_REDISTRIBUTABLE_NAME "vc_redist.x64.exe" CACHE FILEPATH "Name of Microsoft Visual Studio Redistributable") - set(redistPath "${redistPath}/${VISUAL_STUDIO_REDISTRIBUTABLE_NAME}") - else() - set(VISUAL_STUDIO_REDISTRIBUTABLE_NAME "vc_redist.x86.exe" CACHE FILEPATH "Name of Microsoft Visual Studio Redistributable") - set(redistPath "${redistPath}/${VISUAL_STUDIO_REDISTRIBUTABLE_NAME}") - endif() - if(EXISTS ${redistPath}) - set(VISUAL_STUDIO_REDISTRIBUTABLE_PATH ${redistPath} CACHE FILEPATH "Path to the appropriate Microsoft Visual Studio Redistributable") - endif() - endif() - endif() -endif(WINDOWS) \ No newline at end of file diff --git a/indra/cmake/InstallRequiredSystemLibrariesAL.cmake b/indra/cmake/InstallRequiredSystemLibrariesAL.cmake new file mode 100644 index 000000000..0498da38c --- /dev/null +++ b/indra/cmake/InstallRequiredSystemLibrariesAL.cmake @@ -0,0 +1,741 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +#[=======================================================================[.rst: +InstallRequiredSystemLibraries +------------------------------ + +Include this module to search for compiler-provided system runtime +libraries and add install rules for them. Some optional variables +may be set prior to including the module to adjust behavior: + +``CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS`` + Specify additional runtime libraries that may not be detected. + After inclusion any detected libraries will be appended to this. + +``CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_SKIP`` + Set to TRUE to skip calling the :command:`install(PROGRAMS)` command to + allow the includer to specify its own install rule, using the value of + ``CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS`` to get the list of libraries. + +``CMAKE_INSTALL_DEBUG_LIBRARIES`` + Set to TRUE to install the debug runtime libraries when available + with MSVC tools. + +``CMAKE_INSTALL_DEBUG_LIBRARIES_ONLY`` + Set to TRUE to install only the debug runtime libraries with MSVC + tools even if the release runtime libraries are also available. + +``CMAKE_INSTALL_UCRT_LIBRARIES`` + Set to TRUE to install the Windows Universal CRT libraries for + app-local deployment (e.g. to Windows XP). This is meaningful + only with MSVC from Visual Studio 2015 or higher. + + One may set a ``CMAKE_WINDOWS_KITS_10_DIR`` *environment variable* + to an absolute path to tell CMake to look for Windows 10 SDKs in + a custom location. The specified directory is expected to contain + ``Redist/ucrt/DLLs/*`` directories. + +``CMAKE_INSTALL_MFC_LIBRARIES`` + Set to TRUE to install the MSVC MFC runtime libraries. + +``CMAKE_INSTALL_OPENMP_LIBRARIES`` + Set to TRUE to install the MSVC OpenMP runtime libraries + +``CMAKE_INSTALL_SYSTEM_RUNTIME_DESTINATION`` + Specify the :command:`install(PROGRAMS)` command ``DESTINATION`` + option. If not specified, the default is ``bin`` on Windows + and ``lib`` elsewhere. + +``CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_NO_WARNINGS`` + Set to TRUE to disable warnings about required library files that + do not exist. (For example, Visual Studio Express editions may + not provide the redistributable files.) + +``CMAKE_INSTALL_SYSTEM_RUNTIME_COMPONENT`` + Specify the :command:`install(PROGRAMS)` command ``COMPONENT`` + option. If not specified, no such option will be used. +#]=======================================================================] + +cmake_policy(PUSH) +cmake_policy(SET CMP0054 NEW) # if() quoted variables not dereferenced + +set(_IRSL_HAVE_Intel FALSE) +set(_IRSL_HAVE_MSVC FALSE) +foreach(LANG IN ITEMS C CXX Fortran) + if("${CMAKE_${LANG}_COMPILER_ID}" STREQUAL "Intel") + if(NOT _IRSL_HAVE_Intel) + get_filename_component(_Intel_basedir "${CMAKE_${LANG}_COMPILER}" PATH) + if(CMAKE_SIZEOF_VOID_P EQUAL 8) + set(_Intel_archdir intel64) + else() + set(_Intel_archdir x86) + endif() + set(_Intel_compiler_ver ${CMAKE_${LANG}_COMPILER_VERSION}) + if(WIN32) + get_filename_component(_Intel_redistdir "${_Intel_basedir}/../../redist/${_Intel_archdir}/compiler" ABSOLUTE) + elseif(APPLE) + get_filename_component(_Intel_redistdir "${_Intel_basedir}/../../compiler/lib" ABSOLUTE) + else() + if(EXISTS "${_Intel_basedir}/../lib/${_Intel_archdir}_lin") + get_filename_component(_Intel_redistdir "${_Intel_basedir}/../lib/${_Intel_archdir}" ABSOLUTE) + else() + get_filename_component(_Intel_redistdir "${_Intel_basedir}/../../compiler/lib/${_Intel_archdir}_lin" ABSOLUTE) + endif() + endif() + set(_IRSL_HAVE_Intel TRUE) + endif() + elseif("${CMAKE_${LANG}_COMPILER_ID}" STREQUAL "MSVC") + set(_IRSL_HAVE_MSVC TRUE) + endif() +endforeach() + +if(MSVC) + file(TO_CMAKE_PATH "$ENV{SYSTEMROOT}" SYSTEMROOT) + + if(CMAKE_CL_64) + if(MSVC_VERSION GREATER 1599) + # VS 10 and later: + set(CMAKE_MSVC_ARCH x64) + else() + # VS 9 and earlier: + set(CMAKE_MSVC_ARCH amd64) + endif() + else() + set(CMAKE_MSVC_ARCH x86) + endif() + + get_filename_component(devenv_dir "${CMAKE_MAKE_PROGRAM}" PATH) + get_filename_component(base_dir "${devenv_dir}/../.." ABSOLUTE) + + if(MSVC_VERSION EQUAL 1300) + set(__install__libs + "${SYSTEMROOT}/system32/msvcp70.dll" + "${SYSTEMROOT}/system32/msvcr70.dll" + ) + endif() + + if(MSVC_VERSION EQUAL 1310) + set(__install__libs + "${SYSTEMROOT}/system32/msvcp71.dll" + "${SYSTEMROOT}/system32/msvcr71.dll" + ) + endif() + + if(MSVC_TOOLSET_VERSION EQUAL 80) + # Find the runtime library redistribution directory. + get_filename_component(msvc_install_dir + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\8.0;InstallDir]" ABSOLUTE) + if(DEFINED MSVC80_REDIST_DIR AND EXISTS "${MSVC80_REDIST_DIR}") + set(MSVC_REDIST_DIR "${MSVC80_REDIST_DIR}") # use old cache entry + endif() + find_path(MSVC_REDIST_DIR NAMES ${CMAKE_MSVC_ARCH}/Microsoft.VC80.CRT/Microsoft.VC80.CRT.manifest + PATHS + "${msvc_install_dir}/../../VC/redist" + "${base_dir}/VC/redist" + ) + mark_as_advanced(MSVC_REDIST_DIR) + set(MSVC_CRT_DIR "${MSVC_REDIST_DIR}/${CMAKE_MSVC_ARCH}/Microsoft.VC80.CRT") + + # Install the manifest that allows DLLs to be loaded from the + # directory containing the executable. + if(NOT CMAKE_INSTALL_DEBUG_LIBRARIES_ONLY) + set(__install__libs + "${MSVC_CRT_DIR}/Microsoft.VC80.CRT.manifest" + "${MSVC_CRT_DIR}/msvcm80.dll" + "${MSVC_CRT_DIR}/msvcp80.dll" + "${MSVC_CRT_DIR}/msvcr80.dll" + ) + else() + set(__install__libs) + endif() + + if(CMAKE_INSTALL_DEBUG_LIBRARIES) + set(MSVC_CRT_DIR + "${MSVC_REDIST_DIR}/Debug_NonRedist/${CMAKE_MSVC_ARCH}/Microsoft.VC80.DebugCRT") + set(__install__libs ${__install__libs} + "${MSVC_CRT_DIR}/Microsoft.VC80.DebugCRT.manifest" + "${MSVC_CRT_DIR}/msvcm80d.dll" + "${MSVC_CRT_DIR}/msvcp80d.dll" + "${MSVC_CRT_DIR}/msvcr80d.dll" + ) + endif() + endif() + + if(MSVC_TOOLSET_VERSION EQUAL 90) + # Find the runtime library redistribution directory. + get_filename_component(msvc_install_dir + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\9.0;InstallDir]" ABSOLUTE) + get_filename_component(msvc_express_install_dir + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VCExpress\\9.0;InstallDir]" ABSOLUTE) + if(DEFINED MSVC90_REDIST_DIR AND EXISTS "${MSVC90_REDIST_DIR}") + set(MSVC_REDIST_DIR "${MSVC90_REDIST_DIR}") # use old cache entry + endif() + find_path(MSVC_REDIST_DIR NAMES ${CMAKE_MSVC_ARCH}/Microsoft.VC90.CRT/Microsoft.VC90.CRT.manifest + PATHS + "${msvc_install_dir}/../../VC/redist" + "${msvc_express_install_dir}/../../VC/redist" + "${base_dir}/VC/redist" + ) + mark_as_advanced(MSVC_REDIST_DIR) + set(MSVC_CRT_DIR "${MSVC_REDIST_DIR}/${CMAKE_MSVC_ARCH}/Microsoft.VC90.CRT") + + # Install the manifest that allows DLLs to be loaded from the + # directory containing the executable. + if(NOT CMAKE_INSTALL_DEBUG_LIBRARIES_ONLY) + set(__install__libs + "${MSVC_CRT_DIR}/Microsoft.VC90.CRT.manifest" + "${MSVC_CRT_DIR}/msvcm90.dll" + "${MSVC_CRT_DIR}/msvcp90.dll" + "${MSVC_CRT_DIR}/msvcr90.dll" + ) + else() + set(__install__libs) + endif() + + if(CMAKE_INSTALL_DEBUG_LIBRARIES) + set(MSVC_CRT_DIR + "${MSVC_REDIST_DIR}/Debug_NonRedist/${CMAKE_MSVC_ARCH}/Microsoft.VC90.DebugCRT") + set(__install__libs ${__install__libs} + "${MSVC_CRT_DIR}/Microsoft.VC90.DebugCRT.manifest" + "${MSVC_CRT_DIR}/msvcm90d.dll" + "${MSVC_CRT_DIR}/msvcp90d.dll" + "${MSVC_CRT_DIR}/msvcr90d.dll" + ) + endif() + endif() + + set(MSVC_REDIST_NAME "") + set(_MSVC_DLL_VERSION "") + set(_MSVC_IDE_VERSION "") + if(MSVC_VERSION GREATER_EQUAL 2000) + message(WARNING "MSVC ${MSVC_VERSION} not yet supported.") + elseif(MSVC_VERSION_VERSION GREATER_EQUAL 143) + message(WARNING "MSVC toolset v${MSVC_VERSION_VERSION} not yet supported.") + elseif(MSVC_TOOLSET_VERSION EQUAL 142) + set(MSVC_REDIST_NAME VC142) + set(_MSVC_DLL_VERSION 140) + set(_MSVC_IDE_VERSION 16) + if(MSVC_VERSION EQUAL 1920) + # VS2019 named this differently prior to update 1. + set(MSVC_REDIST_NAME VC141) + endif() + elseif(MSVC_TOOLSET_VERSION EQUAL 141) + set(MSVC_REDIST_NAME VC141) + set(_MSVC_DLL_VERSION 140) + set(_MSVC_IDE_VERSION 15) + if(MSVC_VERSION EQUAL 1910) + # VS2017 named this differently prior to update 3. + set(MSVC_REDIST_NAME VC150) + endif() + elseif(MSVC_TOOLSET_VERSION) + set(MSVC_REDIST_NAME VC${MSVC_TOOLSET_VERSION}) + math(EXPR _MSVC_DLL_VERSION "${MSVC_TOOLSET_VERSION} / 10 * 10") + math(EXPR _MSVC_IDE_VERSION "${MSVC_TOOLSET_VERSION} / 10") + endif() + + set(_MSVCRT_DLL_VERSION "") + set(_MSVCRT_IDE_VERSION "") + if(_MSVC_IDE_VERSION GREATER_EQUAL 10) + set(_MSVCRT_DLL_VERSION "${_MSVC_DLL_VERSION}") + set(_MSVCRT_IDE_VERSION "${_MSVC_IDE_VERSION}") + endif() + + if(_MSVCRT_DLL_VERSION) + set(v "${_MSVCRT_DLL_VERSION}") + set(vs "${_MSVCRT_IDE_VERSION}") + + # Find the runtime library redistribution directory. + if(vs VERSION_LESS 15 AND DEFINED MSVC${vs}_REDIST_DIR AND EXISTS "${MSVC${vs}_REDIST_DIR}") + set(MSVC_REDIST_DIR "${MSVC${vs}_REDIST_DIR}") # use old cache entry + endif() + if(NOT vs VERSION_LESS 15) + set(_vs_redist_paths "") + cmake_host_system_information(RESULT _vs_dir QUERY VS_${vs}_DIR) # undocumented query + if(IS_DIRECTORY "${_vs_dir}") + file(GLOB _vs_redist_paths "${_vs_dir}/VC/Redist/MSVC/*") + endif() + unset(_vs_dir) + else() + get_filename_component(_vs_dir + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\${vs}.0;InstallDir]" ABSOLUTE) + set(programfilesx86 "ProgramFiles(x86)") + set(_vs_redist_paths + "${_vs_dir}/../../VC/redist" + "${base_dir}/VC/redist" + "$ENV{ProgramFiles}/Microsoft Visual Studio ${vs}.0/VC/redist" + "$ENV{${programfilesx86}}/Microsoft Visual Studio ${vs}.0/VC/redist" + ) + unset(_vs_dir) + unset(programfilesx86) + endif() + find_path(MSVC_REDIST_DIR NAMES ${CMAKE_MSVC_ARCH}/Microsoft.${MSVC_REDIST_NAME}.CRT PATHS ${_vs_redist_paths}) + unset(_vs_redist_paths) + mark_as_advanced(MSVC_REDIST_DIR) + set(MSVC_CRT_DIR "${MSVC_REDIST_DIR}/${CMAKE_MSVC_ARCH}/Microsoft.${MSVC_REDIST_NAME}.CRT") + + if(NOT CMAKE_INSTALL_DEBUG_LIBRARIES_ONLY) + set(__install__libs + "${MSVC_CRT_DIR}/msvcp${v}.dll" + ) + if(NOT vs VERSION_LESS 14) + file(GLOB __msvcr_dlls "${MSVC_CRT_DIR}/*.dll") + list(APPEND __install__libs ${__msvcr_dlls}) + else() + list(APPEND __install__libs "${MSVC_CRT_DIR}/msvcr${v}.dll") + endif() + else() + set(__install__libs) + endif() + + if(CMAKE_INSTALL_DEBUG_LIBRARIES) + set(MSVC_CRT_DIR + "${MSVC_REDIST_DIR}/Debug_NonRedist/${CMAKE_MSVC_ARCH}/Microsoft.${MSVC_REDIST_NAME}.DebugCRT") + set(__install__libs ${__install__libs} + "${MSVC_CRT_DIR}/msvcp${v}d.dll" + ) + if(NOT vs VERSION_LESS 14) + list(APPEND __install__libs + "${MSVC_CRT_DIR}/vcruntime${v}d.dll" + "${MSVC_CRT_DIR}/concrt${v}d.dll" + ) + else() + list(APPEND __install__libs "${MSVC_CRT_DIR}/msvcr${v}d.dll") + endif() + endif() + + if(CMAKE_INSTALL_UCRT_LIBRARIES AND NOT vs VERSION_LESS 14) + # Find the Windows Kits directory. + get_filename_component(windows_kits_dir + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots;KitsRoot10]" ABSOLUTE) + set(programfilesx86 "ProgramFiles(x86)") + if(";${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION};$ENV{UCRTVersion};$ENV{WindowsSDKVersion};" MATCHES [=[;(10\.[0-9.]+)[;\]]=]) + set(__ucrt_version "${CMAKE_MATCH_1}/") + else() + set(__ucrt_version "") + endif() + find_path(WINDOWS_KITS_DIR + NAMES + Redist/${__ucrt_version}ucrt/DLLs/${CMAKE_MSVC_ARCH}/ucrtbase.dll + Redist/ucrt/DLLs/${CMAKE_MSVC_ARCH}/ucrtbase.dll + PATHS + $ENV{CMAKE_WINDOWS_KITS_10_DIR} + "${windows_kits_dir}" + "$ENV{ProgramFiles}/Windows Kits/10" + "$ENV{${programfilesx86}}/Windows Kits/10" + ) + mark_as_advanced(WINDOWS_KITS_DIR) + + # Glob the list of UCRT DLLs. + if(NOT CMAKE_INSTALL_DEBUG_LIBRARIES_ONLY) + if(EXISTS "${WINDOWS_KITS_DIR}/Redist/${__ucrt_version}ucrt/DLLs/${CMAKE_MSVC_ARCH}/ucrtbase.dll") + file(GLOB __ucrt_dlls "${WINDOWS_KITS_DIR}/Redist/${__ucrt_version}ucrt/DLLs/${CMAKE_MSVC_ARCH}/*.dll") + else() + file(GLOB __ucrt_dlls "${WINDOWS_KITS_DIR}/Redist/ucrt/DLLs/${CMAKE_MSVC_ARCH}/*.dll") + endif() + list(APPEND __install__libs ${__ucrt_dlls}) + endif() + if(CMAKE_INSTALL_DEBUG_LIBRARIES) + if(EXISTS "${WINDOWS_KITS_DIR}/bin/${__ucrt_version}${CMAKE_MSVC_ARCH}/ucrt/ucrtbased.dll") + file(GLOB __ucrt_dlls "${WINDOWS_KITS_DIR}/bin/${__ucrt_version}${CMAKE_MSVC_ARCH}/ucrt/*.dll") + else() + file(GLOB __ucrt_dlls "${WINDOWS_KITS_DIR}/bin/${CMAKE_MSVC_ARCH}/ucrt/*.dll") + endif() + list(APPEND __install__libs ${__ucrt_dlls}) + endif() + endif() + endif() + + if(CMAKE_INSTALL_MFC_LIBRARIES) + if(MSVC_VERSION EQUAL 1300) + set(__install__libs ${__install__libs} + "${SYSTEMROOT}/system32/mfc70.dll" + ) + endif() + + if(MSVC_VERSION EQUAL 1310) + set(__install__libs ${__install__libs} + "${SYSTEMROOT}/system32/mfc71.dll" + ) + endif() + + if(MSVC_VERSION EQUAL 1400) + if(CMAKE_INSTALL_DEBUG_LIBRARIES) + set(MSVC_MFC_DIR + "${MSVC_REDIST_DIR}/Debug_NonRedist/${CMAKE_MSVC_ARCH}/Microsoft.VC80.DebugMFC") + set(__install__libs ${__install__libs} + "${MSVC_MFC_DIR}/Microsoft.VC80.DebugMFC.manifest" + "${MSVC_MFC_DIR}/mfc80d.dll" + "${MSVC_MFC_DIR}/mfc80ud.dll" + "${MSVC_MFC_DIR}/mfcm80d.dll" + "${MSVC_MFC_DIR}/mfcm80ud.dll" + ) + endif() + + set(MSVC_MFC_DIR "${MSVC_REDIST_DIR}/${CMAKE_MSVC_ARCH}/Microsoft.VC80.MFC") + # Install the manifest that allows DLLs to be loaded from the + # directory containing the executable. + if(NOT CMAKE_INSTALL_DEBUG_LIBRARIES_ONLY) + set(__install__libs ${__install__libs} + "${MSVC_MFC_DIR}/Microsoft.VC80.MFC.manifest" + "${MSVC_MFC_DIR}/mfc80.dll" + "${MSVC_MFC_DIR}/mfc80u.dll" + "${MSVC_MFC_DIR}/mfcm80.dll" + "${MSVC_MFC_DIR}/mfcm80u.dll" + ) + endif() + + # include the language dll's for vs8 as well as the actual dll's + set(MSVC_MFCLOC_DIR "${MSVC_REDIST_DIR}/${CMAKE_MSVC_ARCH}/Microsoft.VC80.MFCLOC") + # Install the manifest that allows DLLs to be loaded from the + # directory containing the executable. + set(__install__libs ${__install__libs} + "${MSVC_MFCLOC_DIR}/Microsoft.VC80.MFCLOC.manifest" + "${MSVC_MFCLOC_DIR}/mfc80chs.dll" + "${MSVC_MFCLOC_DIR}/mfc80cht.dll" + "${MSVC_MFCLOC_DIR}/mfc80enu.dll" + "${MSVC_MFCLOC_DIR}/mfc80esp.dll" + "${MSVC_MFCLOC_DIR}/mfc80deu.dll" + "${MSVC_MFCLOC_DIR}/mfc80fra.dll" + "${MSVC_MFCLOC_DIR}/mfc80ita.dll" + "${MSVC_MFCLOC_DIR}/mfc80jpn.dll" + "${MSVC_MFCLOC_DIR}/mfc80kor.dll" + ) + endif() + + if(MSVC_VERSION EQUAL 1500) + if(CMAKE_INSTALL_DEBUG_LIBRARIES) + set(MSVC_MFC_DIR + "${MSVC_REDIST_DIR}/Debug_NonRedist/${CMAKE_MSVC_ARCH}/Microsoft.VC90.DebugMFC") + set(__install__libs ${__install__libs} + "${MSVC_MFC_DIR}/Microsoft.VC90.DebugMFC.manifest" + "${MSVC_MFC_DIR}/mfc90d.dll" + "${MSVC_MFC_DIR}/mfc90ud.dll" + "${MSVC_MFC_DIR}/mfcm90d.dll" + "${MSVC_MFC_DIR}/mfcm90ud.dll" + ) + endif() + + set(MSVC_MFC_DIR "${MSVC_REDIST_DIR}/${CMAKE_MSVC_ARCH}/Microsoft.VC90.MFC") + # Install the manifest that allows DLLs to be loaded from the + # directory containing the executable. + if(NOT CMAKE_INSTALL_DEBUG_LIBRARIES_ONLY) + set(__install__libs ${__install__libs} + "${MSVC_MFC_DIR}/Microsoft.VC90.MFC.manifest" + "${MSVC_MFC_DIR}/mfc90.dll" + "${MSVC_MFC_DIR}/mfc90u.dll" + "${MSVC_MFC_DIR}/mfcm90.dll" + "${MSVC_MFC_DIR}/mfcm90u.dll" + ) + endif() + + # include the language dll's for vs9 as well as the actual dll's + set(MSVC_MFCLOC_DIR "${MSVC_REDIST_DIR}/${CMAKE_MSVC_ARCH}/Microsoft.VC90.MFCLOC") + # Install the manifest that allows DLLs to be loaded from the + # directory containing the executable. + set(__install__libs ${__install__libs} + "${MSVC_MFCLOC_DIR}/Microsoft.VC90.MFCLOC.manifest" + "${MSVC_MFCLOC_DIR}/mfc90chs.dll" + "${MSVC_MFCLOC_DIR}/mfc90cht.dll" + "${MSVC_MFCLOC_DIR}/mfc90enu.dll" + "${MSVC_MFCLOC_DIR}/mfc90esp.dll" + "${MSVC_MFCLOC_DIR}/mfc90deu.dll" + "${MSVC_MFCLOC_DIR}/mfc90fra.dll" + "${MSVC_MFCLOC_DIR}/mfc90ita.dll" + "${MSVC_MFCLOC_DIR}/mfc90jpn.dll" + "${MSVC_MFCLOC_DIR}/mfc90kor.dll" + ) + endif() + + set(_MFC_DLL_VERSION "") + set(_MFC_IDE_VERSION "") + if(_MSVC_IDE_VERSION GREATER_EQUAL 10) + set(_MFC_DLL_VERSION ${_MSVC_DLL_VERSION}) + set(_MFC_IDE_VERSION ${_MSVC_IDE_VERSION}) + endif() + + if(_MFC_DLL_VERSION) + set(v "${_MFC_DLL_VERSION}") + set(vs "${_MFC_IDE_VERSION}") + + # Starting with VS 15 the MFC DLLs may be in a different directory. + if (NOT vs VERSION_LESS 15) + file(GLOB _MSVC_REDIST_DIRS "${MSVC_REDIST_DIR}/../*") + find_path(MSVC_REDIST_MFC_DIR NAMES ${CMAKE_MSVC_ARCH}/Microsoft.${MSVC_REDIST_NAME}.MFC + PATHS ${_MSVC_REDIST_DIRS} NO_DEFAULT_PATH) + mark_as_advanced(MSVC_REDIST_MFC_DIR) + unset(_MSVC_REDIST_DIRS) + else() + set(MSVC_REDIST_MFC_DIR "${MSVC_REDIST_DIR}") + endif() + + # Multi-Byte Character Set versions of MFC are available as optional + # addon since Visual Studio 12. So for version 12 or higher, check + # whether they are available and exclude them if they are not. + + if(CMAKE_INSTALL_DEBUG_LIBRARIES) + set(MSVC_MFC_DIR + "${MSVC_REDIST_MFC_DIR}/Debug_NonRedist/${CMAKE_MSVC_ARCH}/Microsoft.${MSVC_REDIST_NAME}.DebugMFC") + set(__install__libs ${__install__libs} + "${MSVC_MFC_DIR}/mfc${v}ud.dll" + "${MSVC_MFC_DIR}/mfcm${v}ud.dll" + ) + if("${v}" LESS 12 OR EXISTS "${MSVC_MFC_DIR}/mfc${v}d.dll") + set(__install__libs ${__install__libs} + "${MSVC_MFC_DIR}/mfc${v}d.dll" + ) + endif() + if("${v}" LESS 12 OR EXISTS "${MSVC_MFC_DIR}/mfcm${v}d.dll") + set(__install__libs ${__install__libs} + "${MSVC_MFC_DIR}/mfcm${v}d.dll" + ) + endif() + endif() + + set(MSVC_MFC_DIR "${MSVC_REDIST_MFC_DIR}/${CMAKE_MSVC_ARCH}/Microsoft.${MSVC_REDIST_NAME}.MFC") + if(NOT CMAKE_INSTALL_DEBUG_LIBRARIES_ONLY) + set(__install__libs ${__install__libs} + "${MSVC_MFC_DIR}/mfc${v}u.dll" + "${MSVC_MFC_DIR}/mfcm${v}u.dll" + ) + if("${v}" LESS 12 OR EXISTS "${MSVC_MFC_DIR}/mfc${v}.dll") + set(__install__libs ${__install__libs} + "${MSVC_MFC_DIR}/mfc${v}.dll" + ) + endif() + if("${v}" LESS 12 OR EXISTS "${MSVC_MFC_DIR}/mfcm${v}.dll") + set(__install__libs ${__install__libs} + "${MSVC_MFC_DIR}/mfcm${v}.dll" + ) + endif() + endif() + + # include the language dll's as well as the actual dll's + set(MSVC_MFCLOC_DIR "${MSVC_REDIST_MFC_DIR}/${CMAKE_MSVC_ARCH}/Microsoft.${MSVC_REDIST_NAME}.MFCLOC") + set(__install__libs ${__install__libs} + "${MSVC_MFCLOC_DIR}/mfc${v}chs.dll" + "${MSVC_MFCLOC_DIR}/mfc${v}cht.dll" + "${MSVC_MFCLOC_DIR}/mfc${v}deu.dll" + "${MSVC_MFCLOC_DIR}/mfc${v}enu.dll" + "${MSVC_MFCLOC_DIR}/mfc${v}esn.dll" + "${MSVC_MFCLOC_DIR}/mfc${v}fra.dll" + "${MSVC_MFCLOC_DIR}/mfc${v}ita.dll" + "${MSVC_MFCLOC_DIR}/mfc${v}jpn.dll" + "${MSVC_MFCLOC_DIR}/mfc${v}kor.dll" + "${MSVC_MFCLOC_DIR}/mfc${v}rus.dll" + ) + endif() + endif() + + # MSVC 8 was the first version with OpenMP + # Furthermore, there is no debug version of this + if(CMAKE_INSTALL_OPENMP_LIBRARIES AND _IRSL_HAVE_MSVC) + set(_MSOMP_DLL_VERSION ${_MSVC_DLL_VERSION}) + set(_MSOMP_IDE_VERSION ${_MSVC_IDE_VERSION}) + + if(_MSOMP_DLL_VERSION) + set(v "${_MSOMP_DLL_VERSION}") + set(vs "${_MSOMP_IDE_VERSION}") + set(MSVC_OPENMP_DIR "${MSVC_REDIST_DIR}/${CMAKE_MSVC_ARCH}/Microsoft.${MSVC_REDIST_NAME}.OPENMP") + + if(NOT CMAKE_INSTALL_DEBUG_LIBRARIES_ONLY) + set(__install__libs ${__install__libs} + "${MSVC_OPENMP_DIR}/vcomp${v}.dll") + endif() + endif() + endif() + + foreach(lib + ${__install__libs} + ) + if(EXISTS ${lib}) + set(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS + ${CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS} ${lib}) + else() + if(NOT CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_NO_WARNINGS) + message(WARNING "system runtime library file does not exist: '${lib}'") + # This warning indicates an incomplete Visual Studio installation + # or a bug somewhere above here in this file. + # If you would like to avoid this warning, fix the real problem, or + # set CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_NO_WARNINGS before including + # this file. + endif() + endif() + endforeach() +endif() + +if(_IRSL_HAVE_Intel) + unset(__install_libs) + if(CMAKE_INSTALL_OPENMP_LIBRARIES) + if(WIN32) + list(APPEND __install_libs "${_Intel_redistdir}/libiomp5md.dll" "${_Intel_redistdir}/libiompstubs5md.dll") + elseif(APPLE) + list(APPEND __install_libs "${_Intel_redistdir}/libiomp5.dylib" "${_Intel_redistdir}/libiompstubs5.dylib") + else() + list(APPEND __install_libs "${_Intel_redistdir}/libiomp5.so" "${_Intel_redistdir}/libiompstubs5.so") + if(_Intel_compiler_ver VERSION_LESS 17) + list(APPEND __install_libs "${_Intel_redistdir}/libomp_db.so") + endif() + if(_Intel_compiler_ver VERSION_LESS 13) + list(APPEND __install_libs "${_Intel_redistdir}/libiompprof5.so") + endif() + endif() + endif() + if(WIN32) + set(__install_dirs "${_Intel_redistdir}/1033") + if(EXISTS "${_Intel_redistdir}/1041") + list(APPEND __install_dirs "${_Intel_redistdir}/1041") + endif() + if(_Intel_compiler_ver VERSION_LESS 18) + list(APPEND __install_dirs "${_Intel_redistdir}/irml" "${_Intel_redistdir}/irml_c") + endif() + foreach(__Intel_lib IN ITEMS cilkrts20.dll libchkp.dll libioffload_host.dll libirngmd.dll + libmmd.dll libmmdd.dll libmpx.dll liboffload.dll svml_dispmd.dll) + + list(APPEND __install_libs "${_Intel_redistdir}/${__Intel_lib}") + endforeach() + if(CMAKE_C_COMPILER_ID STREQUAL Intel OR CMAKE_CXX_COMPILER_ID STREQUAL Intel) + list(APPEND __install_libs "${_Intel_redistdir}/libgfxoffload.dll") + endif() + if(CMAKE_Fortran_COMPILER_ID STREQUAL Intel) + foreach(__Intel_lib IN ITEMS ifdlg100.dll libicaf.dll libifcoremd.dll libifcoremdd.dll libifcorert.dll libifcorertd.dll libifportmd.dll) + + list(APPEND __install_libs "${_Intel_redistdir}/${__Intel_lib}") + endforeach() + endif() + elseif(APPLE) + foreach(__Intel_lib IN ITEMS libchkp.dylib libcilkrts.5.dylib libcilkrts.dylib libimf.dylib libintlc.dylib libirc.dylib libirng.dylib libsvml.dylib) + list(APPEND __install_libs "${_Intel_redistdir}/${__Intel_lib}") + endforeach() + if(CMAKE_C_COMPILER_ID STREQUAL Intel OR CMAKE_CXX_COMPILER_ID STREQUAL Intel) + if(_Intel_compiler_ver VERSION_LESS 17) + list(APPEND __install_libs "${_Intel_redistdir}/libistrconv.dylib") + endif() + endif() + if(CMAKE_Fortran_COMPILER_ID STREQUAL Intel) + foreach(__Intel_lib IN ITEMS libifcore.dylib libifcoremt.dylib libifport.dylib libifportmt.dylib) + + list(APPEND __install_libs "${_Intel_redistdir}/${__Intel_lib}") + endforeach() + endif() + else() + foreach(__Intel_lib IN ITEMS libchkp.so libcilkrts.so libcilkrts.so.5 libimf.so libintlc.so libintlc.so.5 libirc.so libpdbx.so libpdbx.so.5 libsvml.so) + + list(APPEND __install_libs "${_Intel_redistdir}/${__Intel_lib}") + endforeach() + if(_Intel_compiler_ver VERSION_GREATER_EQUAL 13) + foreach(__Intel_lib IN ITEMS libirng.so liboffload.so liboffload.so.5) + + list(APPEND __install_libs "${_Intel_redistdir}/${__Intel_lib}") + endforeach() + endif() + if(CMAKE_C_COMPILER_ID STREQUAL Intel OR CMAKE_CXX_COMPILER_ID STREQUAL Intel) + set(__install_dirs "${_Intel_redistdir}/irml") + list(APPEND __install_libs "${_Intel_redistdir}/cilk_db.so") + if(_Intel_compiler_ver VERSION_GREATER_EQUAL 15) + list(APPEND __install_libs "${_Intel_redistdir}/libistrconv.so" "${_Intel_redistdir}/libgfxoffload.so") + endif() + endif() + if(_Intel_compiler_ver VERSION_GREATER_EQUAL 16) + foreach(__Intel_lib IN ITEMS libioffload_host.so libioffload_host.so.5 libioffload_target.so libioffload_target.so.5 libmpx.so offload_main) + + list(APPEND __install_libs "${_Intel_redistdir}/${__Intel_lib}") + endforeach() + endif() + if(_Intel_compiler_ver VERSION_LESS 15) + foreach(__Intel_lib IN ITEMS libcxaguard.so libcxaguard.so.5) + + list(APPEND __install_libs "${_Intel_redistdir}/${__Intel_lib}") + endforeach() + endif() + if(CMAKE_Fortran_COMPILER_ID STREQUAL Intel) + foreach(__Intel_lib IN ITEMS libicaf.so libifcore.so libifcore.so.5 libifcoremt.so libifcoremt.so.5 libifport.so libifport.so.5) + + list(APPEND __install_libs "${_Intel_redistdir}/${__Intel_lib}") + endforeach() + endif() + endif() + + foreach(lib IN LISTS __install_libs) + if(EXISTS ${lib}) + list(APPEND CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS ${lib}) + else() + if(NOT CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_NO_WARNINGS) + message(WARNING "system runtime library file does not exist: '${lib}'") + endif() + endif() + endforeach() + + foreach(dir IN LISTS __install_dirs) + if(EXISTS ${dir}) + list(APPEND CMAKE_INSTALL_SYSTEM_RUNTIME_DIRECTORIES ${dir}) + else() + if(NOT CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_NO_WARNINGS) + message(WARNING "system runtime library file does not exist: '${dir}'") + endif() + endif() + endforeach() +endif() + +if(WATCOM) + get_filename_component( CompilerPath ${CMAKE_C_COMPILER} PATH ) + if(CMAKE_C_COMPILER_VERSION) + set(_compiler_version ${CMAKE_C_COMPILER_VERSION}) + else() + set(_compiler_version ${CMAKE_CXX_COMPILER_VERSION}) + endif() + string(REGEX MATCHALL "[0-9]+" _watcom_version_list "${_compiler_version}") + list(GET _watcom_version_list 0 _watcom_major) + list(GET _watcom_version_list 1 _watcom_minor) + set( __install__libs + ${CompilerPath}/clbr${_watcom_major}${_watcom_minor}.dll + ${CompilerPath}/mt7r${_watcom_major}${_watcom_minor}.dll + ${CompilerPath}/plbr${_watcom_major}${_watcom_minor}.dll ) + foreach(lib + ${__install__libs} + ) + if(EXISTS ${lib}) + set(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS + ${CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS} ${lib}) + else() + if(NOT CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_NO_WARNINGS) + message(WARNING "system runtime library file does not exist: '${lib}'") + # This warning indicates an incomplete Watcom installation + # or a bug somewhere above here in this file. + # If you would like to avoid this warning, fix the real problem, or + # set CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_NO_WARNINGS before including + # this file. + endif() + endif() + endforeach() +endif() + + +# Include system runtime libraries in the installation if any are +# specified by CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS. +if(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS) + if(NOT CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_SKIP) + if(NOT CMAKE_INSTALL_SYSTEM_RUNTIME_DESTINATION) + if(WIN32) + set(CMAKE_INSTALL_SYSTEM_RUNTIME_DESTINATION bin) + else() + set(CMAKE_INSTALL_SYSTEM_RUNTIME_DESTINATION lib) + endif() + endif() + if(CMAKE_INSTALL_SYSTEM_RUNTIME_COMPONENT) + set(_CMAKE_INSTALL_SYSTEM_RUNTIME_COMPONENT + COMPONENT ${CMAKE_INSTALL_SYSTEM_RUNTIME_COMPONENT}) + endif() + install(PROGRAMS ${CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS} + DESTINATION ${CMAKE_INSTALL_SYSTEM_RUNTIME_DESTINATION} + ${_CMAKE_INSTALL_SYSTEM_RUNTIME_COMPONENT} + ) + + install(DIRECTORY ${CMAKE_INSTALL_SYSTEM_RUNTIME_DIRECTORIES} + DESTINATION ${CMAKE_INSTALL_SYSTEM_RUNTIME_DESTINATION} + ${_CMAKE_INSTALL_SYSTEM_RUNTIME_COMPONENT} + ) + endif() +endif() + +cmake_policy(POP) diff --git a/indra/cmake/Python.cmake b/indra/cmake/Python.cmake index 83a0690c6..06634cb5d 100644 --- a/indra/cmake/Python.cmake +++ b/indra/cmake/Python.cmake @@ -5,22 +5,30 @@ set(PYTHONINTERP_FOUND) if (WINDOWS) # On Windows, explicitly avoid Cygwin Python. - find_program(PYTHON_EXECUTABLE - NAMES python25.exe python23.exe python.exe - NO_DEFAULT_PATH # added so that cmake does not find cygwin python - PATHS - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\2.7\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\2.6\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\2.5\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\2.4\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\2.3\\InstallPath] - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\2.7\\InstallPath] - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\2.6\\InstallPath] - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\2.5\\InstallPath] - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\2.4\\InstallPath] - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\2.3\\InstallPath] - ) - + if (DEFINED ENV{VIRTUAL_ENV}) + find_program(PYTHON_EXECUTABLE + NAMES python.exe + PATHS + "$ENV{VIRTUAL_ENV}\\scripts" + NO_DEFAULT_PATH + ) + else() + find_program(PYTHON_EXECUTABLE + NAMES python25.exe python23.exe python.exe + NO_DEFAULT_PATH # added so that cmake does not find cygwin python + PATHS + [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\2.7\\InstallPath] + [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\2.6\\InstallPath] + [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\2.5\\InstallPath] + [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\2.4\\InstallPath] + [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\2.3\\InstallPath] + [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\2.7\\InstallPath] + [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\2.6\\InstallPath] + [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\2.5\\InstallPath] + [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\2.4\\InstallPath] + [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\2.3\\InstallPath] + ) + endif() elseif (EXISTS /etc/arch-release) # On Archlinux, use Python 2 diff --git a/indra/libndhacd/CMakeLists.txt b/indra/libndhacd/CMakeLists.txt index 28c4d2f9a..ce520fbdc 100644 --- a/indra/libndhacd/CMakeLists.txt +++ b/indra/libndhacd/CMakeLists.txt @@ -33,3 +33,8 @@ set_source_files_properties(${libndhacd_HEADER_FILES} add_library( nd_hacdConvexDecomposition STATIC ${libndhacd_SOURCE_FILES} ${libndhacd_HEADER_FILES}) +target_link_libraries( + nd_hacdConvexDecomposition + PUBLIC + llcommon + ) diff --git a/indra/libpathing/CMakeLists.txt b/indra/libpathing/CMakeLists.txt index 2ab424822..aefe1a2ac 100644 --- a/indra/libpathing/CMakeLists.txt +++ b/indra/libpathing/CMakeLists.txt @@ -30,3 +30,8 @@ set_source_files_properties(${libpathing_HEADER_FILES} PROPERTIES HEADER_FILE_ONLY TRUE) add_library(nd_Pathing STATIC ${libpathing_SOURCE_FILES} ${libpathing_HEADER_FILES} ) + +target_link_libraries(nd_Pathing + PUBLIC + llcommon +) diff --git a/indra/llaudio/CMakeLists.txt b/indra/llaudio/CMakeLists.txt index f6ea97d07..a200a456e 100644 --- a/indra/llaudio/CMakeLists.txt +++ b/indra/llaudio/CMakeLists.txt @@ -81,3 +81,9 @@ set_source_files_properties(${llaudio_HEADER_FILES} list(APPEND llaudio_SOURCE_FILES ${llaudio_HEADER_FILES}) add_library (llaudio ${llaudio_SOURCE_FILES}) + +target_link_libraries( + llaudio + PUBLIC + llcommon + ) diff --git a/indra/llcharacter/CMakeLists.txt b/indra/llcharacter/CMakeLists.txt index a698a9847..e95b92436 100644 --- a/indra/llcharacter/CMakeLists.txt +++ b/indra/llcharacter/CMakeLists.txt @@ -77,3 +77,9 @@ set_source_files_properties(${llcharacter_HEADER_FILES} list(APPEND llcharacter_SOURCE_FILES ${llcharacter_HEADER_FILES}) add_library (llcharacter ${llcharacter_SOURCE_FILES}) + +target_link_libraries( + llcharacter + PUBLIC + llcommon + ) diff --git a/indra/llcharacter/llmotioncontroller.h b/indra/llcharacter/llmotioncontroller.h index e26d5d088..843cac425 100644 --- a/indra/llcharacter/llmotioncontroller.h +++ b/indra/llcharacter/llmotioncontroller.h @@ -162,7 +162,7 @@ public: void pauseAllMotions(); void unpauseAllMotions(); BOOL isPaused() const { return mPaused; } - U32 getPausedFrame() const { return mPausedFrame; } + U64 getPausedFrame() const { return mPausedFrame; } // void requestPause(std::vector& avatar_pause_handles); void pauseAllSyncedCharacters(std::vector& avatar_pause_handles); @@ -252,7 +252,7 @@ protected: F32 mLastTime; BOOL mHasRunOnce; BOOL mPaused; - U32 mPausedFrame; + U64 mPausedFrame; F32 mTimeStep; S32 mTimeStepCount; F32 mLastInterp; diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index b59485a06..6479c7bca 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -4,7 +4,9 @@ project(llcommon) include(Cwdebug) include(00-Common) +include(Linking) include(LLCommon) +include(EXPAT) include(APR) include(Linking) include(Boost) @@ -287,6 +289,8 @@ endif(LLCOMMON_LINK_SHARED) target_link_libraries( llcommon + PUBLIC + absl::hash ${BREAKPAD_EXCEPTION_HANDLER_LIBRARIES} ${APRUTIL_LIBRARIES} ${APR_LIBRARIES} diff --git a/indra/llcommon/aisyncclient.cpp b/indra/llcommon/aisyncclient.cpp index c62d88efb..191a2627d 100644 --- a/indra/llcommon/aisyncclient.cpp +++ b/indra/llcommon/aisyncclient.cpp @@ -90,7 +90,7 @@ bool operator==(AISyncKey const& key1, AISyncKey const& key2) { // Test if these keys match based on time. - if (std::abs((S32)(key1.mStartFrameCount - key2.mStartFrameCount)) > 1 && + if (std::abs((S64)(key1.mStartFrameCount - key2.mStartFrameCount)) > 1 && std::abs(key1.mFrameTimer.getStartTime() - key2.mFrameTimer.getStartTime()) >= sSyncKeyExpirationTime) { return false; @@ -420,7 +420,7 @@ void AISyncServerMap::remove_server(AISyncServer* server) #include //static -U32 LLFrameTimer::sFrameCount; +U64 LLFrameTimer::sFrameCount; double innerloop_count = 0; diff --git a/indra/llcommon/aisyncclient.h b/indra/llcommon/aisyncclient.h index 0f5237f99..eecad2924 100644 --- a/indra/llcommon/aisyncclient.h +++ b/indra/llcommon/aisyncclient.h @@ -56,8 +56,8 @@ struct LLFrameTimer double mStartTime; double mExpiry; static double getCurrentTime(void); - static U32 sFrameCount; - static U32 getFrameCount() { return sFrameCount; } + static U64 sFrameCount; + static U64 getFrameCount() { return sFrameCount; } F64 getStartTime() const { return mStartTime; } void reset(double expiration) { mStartTime = getCurrentTime(); mExpiry = mStartTime + expiration; } bool hasExpired(void) const { return getCurrentTime() > mExpiry; } @@ -114,7 +114,7 @@ class LL_COMMON_API AISyncKey { private: LLFrameTimer mFrameTimer; // This timer is started at the moment the sync key is created. - U32 mStartFrameCount; // The frame count at which the timer was started. + U64 mStartFrameCount; // The frame count at which the timer was started. public: // Constructor. diff --git a/indra/llcommon/llframetimer.cpp b/indra/llcommon/llframetimer.cpp index 94f0c1dee..a79c47081 100644 --- a/indra/llcommon/llframetimer.cpp +++ b/indra/llcommon/llframetimer.cpp @@ -43,7 +43,7 @@ F64 LLFrameTimer::sTotalSeconds = // Current time in seconds since epoch U64_to_F64(LLFrameTimer::sTotalTime) * USEC_TO_SEC_F64; F64 LLFrameTimer::sFrameTime = 0.0; // Current time in seconds since application start, updated together with LLFrameTimer::sTotalTime. // Updated exactly once per frame: -S32 LLFrameTimer::sFrameCount = 0; // Current frame number (number of frames since application start). +U64 LLFrameTimer::sFrameCount = 0; // Current frame number (number of frames since application start). U64 LLFrameTimer::sPrevTotalTime = LLFrameTimer::sStartTotalTime; // Previous (frame) time in microseconds since epoch, updated once per frame. U64 LLFrameTimer::sFrameDeltaTime = 0; // Microseconds between last two calls to LLFrameTimer::updateFrameTimeAndCount. // Mutex for the above. diff --git a/indra/llcommon/llframetimer.h b/indra/llcommon/llframetimer.h index a2b3ffa39..d0787e9bb 100644 --- a/indra/llcommon/llframetimer.h +++ b/indra/llcommon/llframetimer.h @@ -84,12 +84,12 @@ public: } // Return current frame number (the number of frames since application start). - static U32 getFrameCount(void) + static U64 getFrameCount(void) { // sFrameCount is only accessed by the main thread, so no locking is necessary. llassert(is_main_thread()); //sGlobalMutex.lock(); - U32 res = sFrameCount; + U64 res = sFrameCount; //sGlobalMutex.unlock(); return res; } @@ -185,7 +185,7 @@ protected: static F64 sTotalSeconds; // Current frame number (number of frames since application start). - static S32 sFrameCount; + static U64 sFrameCount; static bool sFirstFrameTimerCreated; diff --git a/indra/llcommon/llkeythrottle.h b/indra/llcommon/llkeythrottle.h index 7544ab1d1..3271a5e33 100644 --- a/indra/llcommon/llkeythrottle.h +++ b/indra/llcommon/llkeythrottle.h @@ -88,7 +88,7 @@ protected: } static U64 getFrame() // Return the current frame number { - return (U64) LLFrameTimer::getFrameCount(); + return LLFrameTimer::getFrameCount(); } }; diff --git a/indra/llcommon/lluuid.h b/indra/llcommon/lluuid.h index 7923d50db..8e5f4e02a 100644 --- a/indra/llcommon/lluuid.h +++ b/indra/llcommon/lluuid.h @@ -34,6 +34,7 @@ #include #include "stdtypes.h" #include "llpreprocessor.h" +#include class LLMutex; @@ -94,6 +95,11 @@ public: bool operator<(const LLUUID &rhs) const; bool operator>(const LLUUID &rhs) const; + template + friend H AbslHashValue(H h, const LLUUID& id) { + return H::combine_contiguous(std::move(h), id.mData, UUID_BYTES); + } + // xor functions. Useful since any two random uuids xored together // will yield a determinate third random unique id that can be // used as a key in a single uuid that represents 2. @@ -294,24 +300,22 @@ typedef std::set uuid_list_t; namespace std { template <> struct hash -{ - public: + { size_t operator()(const LLUUID & id) const { - return id.hash(); + return absl::Hash{}(id); } }; } namespace boost { - template<> class hash -{ - public: - size_t operator()(const LLUUID& id) const + template<> struct hash { - return id.hash(); - } -}; + size_t operator()(const LLUUID& id) const + { + return absl::Hash{}(id); + } + }; } /* diff --git a/indra/llimage/CMakeLists.txt b/indra/llimage/CMakeLists.txt index e05eebc32..fb4188032 100644 --- a/indra/llimage/CMakeLists.txt +++ b/indra/llimage/CMakeLists.txt @@ -57,6 +57,8 @@ add_library (llimage ${llimage_SOURCE_FILES}) target_link_libraries( llimage + PUBLIC + llcommon ${JPEG_LIBRARIES} ${PNG_LIBRARIES} ${ZLIB_LIBRARIES} diff --git a/indra/llimagej2coj/CMakeLists.txt b/indra/llimagej2coj/CMakeLists.txt index af7d35601..2d2a5c86f 100644 --- a/indra/llimagej2coj/CMakeLists.txt +++ b/indra/llimagej2coj/CMakeLists.txt @@ -44,6 +44,8 @@ add_library (llimagej2coj ${llimagej2coj_SOURCE_FILES}) target_link_libraries( llimagej2coj + PUBLIC + llcommon ${OPENJPEG_LIBRARIES} ) diff --git a/indra/llinventory/CMakeLists.txt b/indra/llinventory/CMakeLists.txt index e0659895e..e9586d500 100644 --- a/indra/llinventory/CMakeLists.txt +++ b/indra/llinventory/CMakeLists.txt @@ -69,3 +69,9 @@ set_source_files_properties(${llinventory_HEADER_FILES} list(APPEND llinventory_SOURCE_FILES ${llinventory_HEADER_FILES}) add_library (llinventory ${llinventory_SOURCE_FILES}) + +target_link_libraries( + llinventory + PUBLIC + llcommon + ) diff --git a/indra/llinventory/llparcel.cpp b/indra/llinventory/llparcel.cpp index 407689b79..a4aaae365 100644 --- a/indra/llinventory/llparcel.cpp +++ b/indra/llinventory/llparcel.cpp @@ -803,7 +803,7 @@ void LLParcel::expirePasses(S32 now) if (entry.mTime != 0 && entry.mTime < now) { - mAccessList.erase(itor++); + itor = mAccessList.erase(itor); } else { @@ -894,7 +894,7 @@ BOOL LLParcel::addToAccessList(const LLUUID& agent_id, S32 time) { if (time == 0 || (entry.mTime != 0 && entry.mTime < time)) { - mAccessList.erase(itor++); + itor = mAccessList.erase(itor); } else { @@ -937,15 +937,18 @@ BOOL LLParcel::addToBanList(const LLUUID& agent_id, S32 time) const LLAccessEntry& entry = (*itor).second; if (entry.mID == agent_id) { - if (time == 0 || (entry.mTime != 0 && entry.mTime < time)) + // Singu Note: Allow amending ban time to be less without needing to remove + //if (time == 0 || (entry.mTime != 0 && entry.mTime < time)) { - mBanList.erase(itor++); + itor = mBanList.erase(itor); } +#if 0 else { // existing one expires later return FALSE; } +#endif } else { @@ -973,7 +976,7 @@ BOOL remove_from_access_array(std::map* list, const LLAccessEntry& entry = (*itor).second; if (entry.mID == agent_id) { - list->erase(itor++); + itor = list->erase(itor); removed = TRUE; } else diff --git a/indra/llmath/CMakeLists.txt b/indra/llmath/CMakeLists.txt index 29bc58b33..e91d08a11 100644 --- a/indra/llmath/CMakeLists.txt +++ b/indra/llmath/CMakeLists.txt @@ -102,3 +102,9 @@ set_source_files_properties(${llmath_HEADER_FILES} list(APPEND llmath_SOURCE_FILES ${llmath_HEADER_FILES}) add_library (llmath ${llmath_SOURCE_FILES}) + +target_link_libraries( + llmath + PUBLIC + llcommon + ) diff --git a/indra/llmessage/CMakeLists.txt b/indra/llmessage/CMakeLists.txt index 84308e2ba..c131b436c 100644 --- a/indra/llmessage/CMakeLists.txt +++ b/indra/llmessage/CMakeLists.txt @@ -219,6 +219,8 @@ add_library (llmessage ${llmessage_SOURCE_FILES}) target_link_libraries( llmessage + PUBLIC + llcommon ${CURL_LIBRARIES} ${CARES_LIBRARIES} ${CRYPTO_LIBRARIES} diff --git a/indra/llmessage/aihttptimeoutpolicy.cpp b/indra/llmessage/aihttptimeoutpolicy.cpp index bbe1d9e6a..705b4770d 100644 --- a/indra/llmessage/aihttptimeoutpolicy.cpp +++ b/indra/llmessage/aihttptimeoutpolicy.cpp @@ -927,7 +927,6 @@ P2(groupProposalBallotResponder, transfer_300s); P(homeLocationResponder); P2(HTTPGetResponder, reply_15s); P(iamHere); -P(iamHereVoice); P2(BGFolderHttpHandler, transfer_300s); P(BGItemHttpHandler); P(lcl_responder); diff --git a/indra/llmessage/llxfermanager.cpp b/indra/llmessage/llxfermanager.cpp index 4cea886c8..3ae02b9f7 100644 --- a/indra/llmessage/llxfermanager.cpp +++ b/indra/llmessage/llxfermanager.cpp @@ -198,7 +198,7 @@ void LLXferManager::updateHostStatus() << " is " << xferp->mXferSize << " bytes" << ", status " << (S32)(xferp->mStatus) << ", waiting for ACK: " << (S32)(xferp->mWaitingForACK) - << " in frame " << (S32) LLFrameTimer::getFrameCount() + << " in frame " << LLFrameTimer::getFrameCount() << LL_ENDL; } @@ -209,7 +209,7 @@ void LLXferManager::updateHostStatus() << " has " << (*iter)->mNumActive << " active, " << (*iter)->mNumPending << " pending" - << " in frame " << (S32) LLFrameTimer::getFrameCount() + << " in frame " << LLFrameTimer::getFrameCount() << LL_ENDL; } #endif // LL_XFER_DIAGNOISTIC_LOGGING diff --git a/indra/llplugin/CMakeLists.txt b/indra/llplugin/CMakeLists.txt index 3c76f7a50..3a903080e 100644 --- a/indra/llplugin/CMakeLists.txt +++ b/indra/llplugin/CMakeLists.txt @@ -58,8 +58,14 @@ list(APPEND llplugin_SOURCE_FILES ${llplugin_HEADER_FILES}) add_library (llplugin ${llplugin_SOURCE_FILES}) if(LINUX AND STANDALONE) - target_link_libraries (llplugin rt dl) -endif(LINUX AND STANDALONE) + target_link_libraries (llplugin llcommon rt dl) +else() + target_link_libraries( + llplugin + PUBLIC + llcommon + ) +endif() add_subdirectory(slplugin) diff --git a/indra/llplugin/slplugin/CMakeLists.txt b/indra/llplugin/slplugin/CMakeLists.txt index f2596a1a6..93a125ea1 100644 --- a/indra/llplugin/slplugin/CMakeLists.txt +++ b/indra/llplugin/slplugin/CMakeLists.txt @@ -1,6 +1,7 @@ project(SLPlugin) include(00-Common) +include(Linking) include(LLCommon) include(LLPlugin) include(Linking) diff --git a/indra/llprimitive/CMakeLists.txt b/indra/llprimitive/CMakeLists.txt index b688e746e..33f51a6f0 100644 --- a/indra/llprimitive/CMakeLists.txt +++ b/indra/llprimitive/CMakeLists.txt @@ -71,3 +71,9 @@ set_source_files_properties(${llprimitive_HEADER_FILES} list(APPEND llprimitive_SOURCE_FILES ${llprimitive_HEADER_FILES}) add_library (llprimitive ${llprimitive_SOURCE_FILES}) + +target_link_libraries( + llprimitive + PUBLIC + llcommon + ) diff --git a/indra/llrender/CMakeLists.txt b/indra/llrender/CMakeLists.txt index 57283e9fe..029afac30 100644 --- a/indra/llrender/CMakeLists.txt +++ b/indra/llrender/CMakeLists.txt @@ -84,3 +84,9 @@ endif (DARWIN) list(APPEND llrender_SOURCE_FILES ${llrender_HEADER_FILES}) add_library (llrender ${llrender_SOURCE_FILES}) + +target_link_libraries( + llrender + PUBLIC + llcommon + ) diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp index 60eae831c..120c378df 100644 --- a/indra/llui/llbutton.cpp +++ b/indra/llui/llbutton.cpp @@ -461,7 +461,7 @@ BOOL LLButton::handleMouseDown(S32 x, S32 y, MASK mask) if(mMouseDownSignal) (*mMouseDownSignal)(this, LLSD()); mMouseDownTimer.start(); - mMouseDownFrame = (S32) LLFrameTimer::getFrameCount(); + mMouseDownFrame = LLFrameTimer::getFrameCount(); mMouseHeldDownCount = 0; @@ -589,7 +589,7 @@ BOOL LLButton::handleHover(S32 x, S32 y, MASK mask) if (mMouseDownTimer.getStarted()) { F32 elapsed = getHeldDownTime(); - if( mHeldDownDelay <= elapsed && mHeldDownFrameDelay <= (S32)LLFrameTimer::getFrameCount() - mMouseDownFrame) + if( mHeldDownDelay <= elapsed && mHeldDownFrameDelay <= LLFrameTimer::getFrameCount() - mMouseDownFrame) { LLSD param; param["count"] = mMouseHeldDownCount++; diff --git a/indra/llui/llbutton.h b/indra/llui/llbutton.h index 812ea6de1..dfa405f63 100644 --- a/indra/llui/llbutton.h +++ b/indra/llui/llbutton.h @@ -319,7 +319,7 @@ protected: const LLFontGL *mGLFont; - S32 mMouseDownFrame; + U64 mMouseDownFrame; S32 mMouseHeldDownCount; // Counter for parameter passed to held-down callback F32 mHeldDownDelay; // seconds, after which held-down callbacks get called S32 mHeldDownFrameDelay; // frames, after which held-down callbacks get called diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index f5fa3ece2..c86e4ae50 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -674,6 +674,31 @@ void LLFloater::close(bool app_quitting) } } + //If floater is a dependent, remove it from parent (dependee) + LLFloater* dependee = mDependeeHandle.get(); + if (dependee) + { + dependee->removeDependentFloater(this); + } + + // now close dependent floater + for (handle_set_iter_t dependent_it = mDependents.begin(); + dependent_it != mDependents.end(); ) + { + LLFloater* floaterp = dependent_it->get(); + if (floaterp) + { + ++dependent_it; + floaterp->close(app_quitting); + } + else + { + mDependents.erase(dependent_it++); + } + } + + cleanupHandles(); + if (!app_quitting && !getControlName().empty()) setControlValue(false); diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp index 1db2638e0..b6279a468 100644 --- a/indra/llui/lllineeditor.cpp +++ b/indra/llui/lllineeditor.cpp @@ -432,6 +432,13 @@ void LLLineEditor::setCursorToEnd() deselect(); } +void LLLineEditor::resetScrollPosition() +{ + mScrollHPos = 0; + // make sure cursor stays in visible range + setCursor(getCursor()); +} + BOOL LLLineEditor::canDeselect() const { return hasSelection(); diff --git a/indra/llui/lllineeditor.h b/indra/llui/lllineeditor.h index 91a7983f4..23cb6333a 100644 --- a/indra/llui/lllineeditor.h +++ b/indra/llui/lllineeditor.h @@ -190,6 +190,9 @@ public: void setCursor( S32 pos ); void setCursorToEnd(); + // set scroll to earliest position it can reasonably be set + void resetScrollPosition(); + // Selects characters 'start' to 'end'. void setSelection(S32 start, S32 end); diff --git a/indra/llui/llscrolllistcell.h b/indra/llui/llscrolllistcell.h index 84c196a05..3cbdc6d3e 100644 --- a/indra/llui/llscrolllistcell.h +++ b/indra/llui/llscrolllistcell.h @@ -78,7 +78,7 @@ public: visible("visible", true), value("value"), tool_tip("tool_tip", ""), - format("format", ""), + format("format", "%D %T"), font("font"/*, LLFontGL::getFontSansSerifSmall()*/), font_color("font_color", LLColor4::black), font_style("font-style"), diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index 2d84791b1..2aa1b17ec 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -54,6 +54,8 @@ #include "llsdparam.h" #include "llmenugl.h" +#include + static LLRegisterWidget r("scroll_list"); @@ -157,6 +159,7 @@ LLScrollListCtrl::LLScrollListCtrl(const std::string& name, const LLRect& rect, mFgUnselectedColor(LLUI::sColorsGroup->getColor("ScrollUnselectedColor")), mFgDisabledColor(LLUI::sColorsGroup->getColor("ScrollDisabledColor")), mHighlightedColor(LLUI::sColorsGroup->getColor("ScrollHighlightedColor")), + mFilter(), mSearchColumn(0), mColumnPadding(5) { @@ -195,7 +198,8 @@ LLScrollListCtrl::LLScrollListCtrl(const std::string& name, const LLRect& rect, addChild(mBorder); } - LLTextBox* textBox = new LLTextBox("comment_text",mItemListRect,std::string()); + LLTextBox* textBox = new LLTextBox("comment_text",mItemListRect, LLStringUtil::null); + mCommentTextView = textBox; textBox->setBorderVisible(false); textBox->setFollows(FOLLOWS_ALL); textBox->setFontShadow(LLFontGL::NO_SHADOW); @@ -312,12 +316,12 @@ std::vector LLScrollListCtrl::getAllSelected() const uuid_vec_t LLScrollListCtrl::getSelectedIDs() { - LLUUID selected_id; uuid_vec_t ids; - std::vector selected = this->getAllSelected(); - for(std::vector::iterator itr = selected.begin(); itr != selected.end(); ++itr) + if (!getCanSelect()) return ids; + + for(const auto& item : mItemList) { - ids.push_back((*itr)->getUUID()); + if (item->getSelected()) ids.push_back(item->getUUID()); } return ids; } @@ -400,6 +404,17 @@ std::vector LLScrollListCtrl::getAllData() const return ret; } +uuid_vec_t LLScrollListCtrl::getAllIDs() const +{ + uuid_vec_t ret; + ret.reserve(mItemList.size()); //Optimization + for(const auto& item : mItemList) + { + ret.push_back(item->getUUID()); + } + return ret; +} + // returns first matching item LLScrollListItem* LLScrollListCtrl::getItem(const LLSD& sd) const { @@ -443,23 +458,27 @@ void LLScrollListCtrl::updateLayout() mCommentTextView->setShape(mItemListRect); - // how many lines of content in a single "page" - S32 page_lines = getLinesPerPage(); + adjustScrollbar(mFilter.empty() ? getItemCount() : mScrollbar->getDocSize()); // Doc size is the item count without a filter, otherwise it's calculated whenever filter is updated + dirtyColumns(); +} - BOOL scrollbar_visible = mLineHeight * getItemCount() > mItemListRect.getHeight(); +void LLScrollListCtrl::adjustScrollbar(S32 doc_size) +{ + // how many lines of content in a single "page" + S32 page_lines = getLinesPerPage(); + + bool scrollbar_visible = mLineHeight * doc_size > mItemListRect.getHeight(); if (scrollbar_visible) { // provide space on the right for scrollbar mItemListRect.mRight = getRect().getWidth() - mBorderThickness - SCROLLBAR_SIZE; + mScrollbar->setOrigin(mItemListRect.mRight, mItemListRect.mBottom); + mScrollbar->reshape(SCROLLBAR_SIZE, mItemListRect.getHeight() + (mDisplayColumnHeaders ? mHeadingHeight : 0)); } - mScrollbar->setOrigin(getRect().getWidth() - mBorderThickness - SCROLLBAR_SIZE, mItemListRect.mBottom); - mScrollbar->reshape(SCROLLBAR_SIZE, mItemListRect.getHeight() + (mDisplayColumnHeaders ? mHeadingHeight : 0)); mScrollbar->setPageSize(page_lines); - mScrollbar->setDocSize( getItemCount() ); + mScrollbar->setDocSize(doc_size); mScrollbar->setVisible(scrollbar_visible); - - dirtyColumns(); } // Attempt to size the control to show all items. @@ -493,6 +512,9 @@ BOOL LLScrollListCtrl::addItem( LLScrollListItem* item, EAddPosition pos, BOOL r BOOL not_too_big = getItemCount() < mMaxItemCount; if (not_too_big) { + if (!mFilter.empty() && !filterItem(item)) // If we're filtering, filter this item if needed, if not, bump the document size. + mScrollbar->setDocSize(mScrollbar->getDocSize()+1); + switch( pos ) { case ADD_TOP: @@ -575,10 +597,11 @@ S32 LLScrollListCtrl::calcMaxContentWidth() { // update max content width for this column, by looking at all items column->mMaxContentWidth = column->mHeader ? LLFontGL::getFontSansSerifSmall()->getWidth(column->mLabel.getWString()) + mColumnPadding + HEADING_TEXT_PADDING : 0; - item_list::iterator iter; - for (iter = mItemList.begin(); iter != mItemList.end(); iter++) + for (auto& item : mItemList) { - LLScrollListCell* cellp = (*iter)->getColumn(column->mIndex); + if (item->getFiltered()) continue; + + LLScrollListCell* cellp = item->getColumn(column->mIndex); if (!cellp) continue; column->mMaxContentWidth = llmax(LLFontGL::getFontSansSerifSmall()->getWidth(cellp->getValue().asString()) + mColumnPadding + COLUMN_TEXT_PADDING, column->mMaxContentWidth); @@ -588,6 +611,7 @@ S32 LLScrollListCtrl::calcMaxContentWidth() } mColumnWidthsDirty = false; + mMaxContentWidth = max_item_width; return max_item_width; } @@ -631,10 +655,8 @@ const S32 SCROLL_LIST_ROW_PAD = 2; void LLScrollListCtrl::updateLineHeight() { mLineHeight = 0; - item_list::iterator iter; - for (iter = mItemList.begin(); iter != mItemList.end(); iter++) + for (auto& itemp : mItemList) { - LLScrollListItem *itemp = *iter; S32 num_cols = itemp->getNumColumns(); S32 i = 0; for (const LLScrollListCell* cell = itemp->getColumn(i); i < num_cols; cell = itemp->getColumn(++i)) @@ -755,6 +777,7 @@ BOOL LLScrollListCtrl::selectFirstItem() for (iter = mItemList.begin(); iter != mItemList.end(); iter++) { LLScrollListItem *itemp = *iter; + if (itemp->getFiltered()) continue; if( first_item && itemp->getEnabled() ) { if (!itemp->getSelected()) @@ -813,13 +836,13 @@ BOOL LLScrollListCtrl::selectItemRange( S32 first_index, S32 last_index ) iter = mItemList.erase(iter); continue ; } - - if( index >= first_index && index <= last_index ) + + if (index >= first_index && index <= last_index) { - if( itemp->getEnabled() ) + if (itemp->getEnabled()) { selectItem(itemp, FALSE); - success = TRUE; + success = TRUE; } } else @@ -962,6 +985,8 @@ S32 LLScrollListCtrl::selectMultiple( uuid_vec_t ids ) for (iter = mItemList.begin(); iter != mItemList.end(); iter++) { LLScrollListItem* item = *iter; + if (item->getFiltered()) continue; + uuid_vec_t::iterator iditr; for(iditr = ids.begin(); iditr != ids.end(); ++iditr) { @@ -987,15 +1012,14 @@ S32 LLScrollListCtrl::getItemIndex( LLScrollListItem* target_item ) const updateSort(); S32 index = 0; - item_list::const_iterator iter; - for (iter = mItemList.begin(); iter != mItemList.end(); iter++) + for (LLScrollListItem* itemp : mItemList) { - LLScrollListItem *itemp = *iter; + if (itemp->getFiltered()) continue; if (target_item == itemp) { return index; } - index++; + ++index; } return -1; } @@ -1005,15 +1029,14 @@ S32 LLScrollListCtrl::getItemIndex( const LLUUID& target_id ) const updateSort(); S32 index = 0; - item_list::const_iterator iter; - for (iter = mItemList.begin(); iter != mItemList.end(); iter++) + for (LLScrollListItem* itemp : mItemList) { - LLScrollListItem *itemp = *iter; + if (itemp->getFiltered()) continue; if (target_id == itemp->getUUID()) { return index; } - index++; + ++index; } return -1; } @@ -1035,6 +1058,7 @@ void LLScrollListCtrl::selectPrevItem( BOOL extend_selection) for (iter = mItemList.begin(); iter != mItemList.end(); iter++) { LLScrollListItem* cur_item = *iter; + if (cur_item->getFiltered()) continue; if (cur_item->getSelected()) { @@ -1079,6 +1103,7 @@ void LLScrollListCtrl::selectNextItem( BOOL extend_selection) for (iter = mItemList.rbegin(); iter != mItemList.rend(); iter++) { LLScrollListItem* cur_item = *iter; + if (cur_item->getFiltered()) continue; if (cur_item->getSelected()) { @@ -1128,7 +1153,7 @@ void LLScrollListCtrl::deselectAllItems(BOOL no_commit_on_change) void LLScrollListCtrl::setCommentText(const std::string& comment_text) { - getChild("comment_text")->setWrappedText(comment_text); + static_cast(mCommentTextView)->setWrappedText(comment_text); } LLScrollListItem* LLScrollListCtrl::addSeparator(EAddPosition pos) @@ -1183,6 +1208,7 @@ LLScrollListItem* LLScrollListCtrl::getItemByLabel(const std::string& label, BOO for (iter = mItemList.begin(); iter != mItemList.end(); iter++) { LLScrollListItem* item = *iter; + std::string item_text = item->getColumn(column)->getValue().asString(); // Only select enabled items with matching names if (!case_sensitive) { @@ -1218,6 +1244,8 @@ BOOL LLScrollListCtrl::selectItemByPrefix(const LLWString& target, BOOL case_sen for (iter = mItemList.begin(); iter != mItemList.end(); iter++) { LLScrollListItem* item = *iter; + if (item->getFiltered()) continue; + // Only select enabled items with matching names LLScrollListCell* cellp = item->getColumn(getSearchColumn()); BOOL select = cellp ? item->getEnabled() && ('\0' == cellp->getValue().asString()[0]) : FALSE; @@ -1241,6 +1269,9 @@ BOOL LLScrollListCtrl::selectItemByPrefix(const LLWString& target, BOOL case_sen { LLScrollListItem* item = *iter; + // Don't select filtered items + if (item->getFiltered()) continue; + // Only select enabled items with matching names LLScrollListCell* cellp = item->getColumn(getSearchColumn()); if (!cellp) @@ -1325,6 +1356,8 @@ BOOL LLScrollListCtrl::setSelectedByValue(const LLSD& value, BOOL selected) for (iter = mItemList.begin(); iter != mItemList.end(); iter++) { LLScrollListItem* item = *iter; + if (item->getFiltered()) continue; + if (item->getEnabled() && (item->getValue().asString() == value.asString())) { if (selected) @@ -1354,7 +1387,7 @@ BOOL LLScrollListCtrl::isSelected(const LLSD& value) const for (iter = mItemList.begin(); iter != mItemList.end(); iter++) { LLScrollListItem* item = *iter; - if (item->getValue().asString() == value.asString()) + if (!item->getFiltered() && item->getValue().asString() == value.asString()) { return item->getSelected(); } @@ -1393,9 +1426,6 @@ void LLScrollListCtrl::drawItems() S32 x = mItemListRect.mLeft; S32 y = mItemListRect.mTop - mLineHeight; - // allow for partial line at bottom - S32 num_page_lines = getLinesPerPage(); - LLRect item_rect; LLGLSUIDefault gls_ui; @@ -1414,27 +1444,32 @@ void LLScrollListCtrl::drawItems() clip_rect.intersectWith(scissor); } - S32 max_columns = 0; - - LLColor4 highlight_color = LLColor4::white; - F32 type_ahead_timeout = LLUI::sConfigGroup->getF32("TypeAheadTimeout"); - highlight_color.mV[VALPHA] = clamp_rescale(mSearchTimer.getElapsedTimeF32(), type_ahead_timeout * 0.7f, type_ahead_timeout, 0.4f, 0.f); - S32 first_line = mScrollLines; - S32 last_line = llmin((S32)mItemList.size() - 1, mScrollLines + getLinesPerPage()); - if ((item_list::size_type)first_line >= mItemList.size()) { return; } + S32 list_size = mItemList.size() - 1; + + // allow for partial line at bottom + S32 num_page_lines = mFilter.empty() ? getLinesPerPage() : mScrollbar->getDocSize() + 1; + S32 last_line = llmin(list_size, mScrollLines + num_page_lines); + + S32 max_columns = 0; + + LLColor4 highlight_color = LLColor4::white; + static const LLUICachedControl type_ahead_timeout("TypeAheadTimeout"); + highlight_color.mV[VALPHA] = clamp_rescale(mSearchTimer.getElapsedTimeF32(), type_ahead_timeout * 0.7f, type_ahead_timeout, 0.4f, 0.f); + bool done = false; for (S32 pass = 0; !done; ++pass) { bool should_continue = false; // False until all passes are done for all row cells. S32 cur_y = y; - for (S32 line = first_line; line <= last_line; line++) + for (S32 index = first_line, line = first_line; index <= list_size; ++index) { - LLScrollListItem* item = mItemList[line]; + LLScrollListItem* item = mItemList[index]; + if (item->getFiltered()) continue; // Skip filtered item_rect.setOriginAndSize( x, @@ -1450,7 +1485,6 @@ void LLScrollListCtrl::drawItems() LLColor4 fg_color; LLColor4 bg_color(LLColor4::transparent); - if (mScrollLines <= line && line < mScrollLines + num_page_lines) { cur_y -= mLineHeight; @@ -1486,6 +1520,10 @@ void LLScrollListCtrl::drawItems() } should_continue |= item->draw(pass, item_rect, fg_color, bg_color, highlight_color, mColumnPadding); + if (++line > last_line) + { + break; // Don't draw any more than needed. + } } } done = !should_continue; @@ -1518,7 +1556,7 @@ void LLScrollListCtrl::draw() updateColumns(); - getChildView("comment_text")->setVisible(mItemList.empty()); + mCommentTextView->setVisible(mItemList.empty()); drawItems(); @@ -1636,9 +1674,10 @@ BOOL LLScrollListCtrl::selectItemAt(S32 x, S32 y, MASK mask) // meaning that we never stop selecting until hitting max or // the end of the list. LLScrollListItem* lastSelected = mLastSelected; + auto selected_count = getAllSelected().size(); for (itor = mItemList.begin(); itor != mItemList.end(); ++itor) { - if(mMaxSelectable > 0 && getAllSelected().size() >= mMaxSelectable) + if(mMaxSelectable > 0 && selected_count >= mMaxSelectable) { if(mOnMaximumSelectCallback) { @@ -1647,6 +1686,7 @@ BOOL LLScrollListCtrl::selectItemAt(S32 x, S32 y, MASK mask) break; } LLScrollListItem *item = *itor; + if (item->getFiltered()) continue; if (item == hit_item || item == lastSelected) { selectItem(item, FALSE); @@ -1661,6 +1701,7 @@ BOOL LLScrollListCtrl::selectItemAt(S32 x, S32 y, MASK mask) { selectItem(item, FALSE); } + ++selected_count; } } } @@ -1788,17 +1829,19 @@ BOOL LLScrollListCtrl::handleDoubleClick(S32 x, S32 y, MASK mask) { // Offer the click to the children, even if we aren't enabled // so the scroll bars will work. - if (NULL == LLView::childrenHandleDoubleClick(x, y, mask)) + handled = LLView::childrenHandleDoubleClick(x, y, mask) != nullptr; + if (!handled) { // Run the callback only if an item is being double-clicked. - if( mCanSelect && hitItem(x, y) && mOnDoubleClickCallback ) + if (mCanSelect && mOnDoubleClickCallback && hitItem(x, y)) { mOnDoubleClickCallback(); + handled = true; } } } - return TRUE; + return handled; } BOOL LLScrollListCtrl::handleClick(S32 x, S32 y, MASK mask) @@ -1871,15 +1914,16 @@ LLScrollListItem* LLScrollListCtrl::hitItem( S32 x, S32 y ) // allow for partial line at bottom S32 num_page_lines = getLinesPerPage(); + S32 list_size = mItemList.size() - 1; + S32 last_line = llmin(list_size, mScrollLines + num_page_lines); - S32 line = 0; - item_list::iterator iter; - for(iter = mItemList.begin(); iter != mItemList.end(); iter++) + for (S32 index = mScrollLines, line = mScrollLines; index <= list_size; ++index) { - LLScrollListItem* item = *iter; - if( mScrollLines <= line && line < mScrollLines + num_page_lines ) + LLScrollListItem* item = mItemList[index]; + if (item->getFiltered()) continue; + { - if( item->getEnabled() && item_rect.pointInRect( x, y ) ) + if (item->getEnabled() && item_rect.pointInRect( x, y )) { hit_item = item; break; @@ -1887,7 +1931,7 @@ LLScrollListItem* LLScrollListCtrl::hitItem( S32 x, S32 y ) item_rect.translate(0, -mLineHeight); } - line++; + if (++line > last_line) break; // Don't try to hit any undrawn items } return hit_item; @@ -1945,6 +1989,58 @@ S32 LLScrollListCtrl::getRowOffsetFromIndex(S32 index) return row_bottom; } +bool LLScrollListCtrl::filterItem(LLScrollListItem* item) +{ + for (const auto& column : item->mColumns) + { + // Only filter text, search tooltip because it'll usually be the text anyway. + if (column->isText() && boost::icontains(column->getToolTip(), mFilter)) + { + item->setFiltered(false); + return false; + } + } + item->setFiltered(true); + return true; +} + +void LLScrollListCtrl::setFilter(const std::string& filter) +{ + if (filter == mFilter) return; + + bool no_filter = filter.empty(); + // If our filter string has been expanded, we can skip already filtered items + bool expanded = !no_filter && !mFilter.empty() && boost::icontains(filter, mFilter); + // If our filter string has been contracted, we can skip already unfiltered items + bool contracted = !no_filter && !mFilter.empty() && !expanded && boost::icontains(mFilter, filter); + bool unique = !expanded && !contracted; + + mFilter = filter; + S32 unfiltered_count = no_filter ? mItemList.size() // No filter, doc size is all items + : !unique ? mScrollbar->getDocSize() // Expanded/contracted filter, start with the current doc size and remove/add respectively + : 0; // Different filter, count up from 0; + for (auto& item : mItemList) + { + if (no_filter) item->setFiltered(false); + else if (expanded && !item->getFiltered()) // Filter has been expanded and we are not yet filtered + { + if (filterItem(item)) --unfiltered_count; // We are now filtered, lower the count + } + else if (unique || // Filter isn't expanded, find out if we should be filtered or + (contracted && item->getFiltered())) // Filter has contracted and we were filtered before, should we still be? + { + if (!filterItem(item)) ++unfiltered_count; // Wasn't filltered, bump count + } + } + + if (mLastSelected && mLastSelected->getFiltered()) // Remove selection if filtered. + mLastSelected = nullptr; + + // Scrollbar needs adjusted + setScrollPos(0); // Changing the filter resets scroll position + adjustScrollbar(unfiltered_count); +} + BOOL LLScrollListCtrl::handleHover(S32 x,S32 y,MASK mask) { @@ -2174,26 +2270,28 @@ BOOL LLScrollListCtrl::handleUnicodeCharHere(llwchar uni_char) while(iter != start_iter) { LLScrollListItem* item = *iter; - - LLScrollListCell* cellp = item->getColumn(getSearchColumn()); - if (cellp) + if (!item->getFiltered()) { - // Only select enabled items with matching first characters - LLWString item_label = utf8str_to_wstring(cellp->getValue().asString()); - if (item->getEnabled() && LLStringOps::toLower(item_label[0]) == uni_char) + LLScrollListCell* cellp = item->getColumn(getSearchColumn()); + if (cellp) { - selectItem(item); - mNeedsScroll = true; - cellp->highlightText(0, 1); - mSearchTimer.reset(); - - if (mCommitOnKeyboardMovement - && !mCommitOnSelectionChange) + // Only select enabled items with matching first characters + LLWString item_label = utf8str_to_wstring(cellp->getValue().asString()); + if (item->getEnabled() && LLStringOps::toLower(item_label[0]) == uni_char) { - onCommit(); - } + selectItem(item); + mNeedsScroll = true; + cellp->highlightText(0, 1); + mSearchTimer.reset(); - break; + if (mCommitOnKeyboardMovement + && !mCommitOnSelectionChange) + { + onCommit(); + } + + break; + } } } @@ -2359,6 +2457,12 @@ void LLScrollListCtrl::onScrollChange( S32 new_pos, LLScrollbar* scrollbar ) } +void LLScrollListCtrl::setSortOrder(const sort_order_t& order) +{ + mSortColumns = order; + updateSort(); +} + void LLScrollListCtrl::sortByColumn(const std::string& name, BOOL ascending) { column_map_t::iterator itor = mColumns.find(name); @@ -2805,7 +2909,7 @@ void LLScrollListCtrl::selectAll() for (iter = mItemList.begin(); iter != mItemList.end(); iter++) { LLScrollListItem *itemp = *iter; - if( itemp->getEnabled() ) + if (itemp->getEnabled() && !itemp->getFiltered()) { selectItem(itemp, FALSE); } diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h index 3a2adf5c6..e52f41ee9 100644 --- a/indra/llui/llscrolllistctrl.h +++ b/indra/llui/llscrolllistctrl.h @@ -207,6 +207,7 @@ public: LLScrollListItem* getFirstData() const; LLScrollListItem* getLastData() const; std::vector getAllData() const; + uuid_vec_t getAllIDs() const; //Helper. Much like getAllData, but just provides a LLUUID vec LLScrollListItem* getItem(const LLSD& sd) const; @@ -248,6 +249,9 @@ public: void clearSearchString() { mSearchString.clear(); } + bool filterItem(LLScrollListItem* item); + void setFilter(const std::string& filter); + // support right-click context menus for avatar/group lists void setContextMenu(LLMenuGL* menu) { mPopupMenu = menu; } void setContextMenu(S32 index) { mPopupMenu = sMenus[index]; } @@ -275,6 +279,7 @@ public: virtual void resetDirty(); // Clear dirty state virtual void updateLayout(); + void adjustScrollbar(S32 doc_size); virtual void fitContents(S32 max_width, S32 max_height); virtual LLRect getRequiredRect(); @@ -321,10 +326,12 @@ public: S32 getTotalStaticColumnWidth() { return mTotalStaticColumnWidth; } typedef std::pair sort_column_t; - const std::vector& getSortColumns() const { return mSortColumns; } + typedef std::vector sort_order_t; + const sort_order_t& getSortOrder() const { return mSortColumns; } std::string getSortColumnName(); BOOL getSortAscending() { return mSortColumns.empty() ? TRUE : mSortColumns.back().second; } BOOL hasSortOrder() const; + void setSortOrder(const sort_order_t& order); void clearSortOrder(); void setSortEnabled(bool sort); @@ -467,6 +474,8 @@ private: LLWString mSearchString; LLFrameTimer mSearchTimer; + + std::string mFilter; S32 mSearchColumn; S32 mNumDynamicWidthColumns; @@ -484,7 +493,7 @@ private: typedef std::vector ordered_columns_t; ordered_columns_t mColumnsIndexed; - std::vector mSortColumns; + sort_order_t mSortColumns; sort_signal_t* mSortCallback; }; // end class LLScrollListCtrl diff --git a/indra/llui/llscrolllistitem.cpp b/indra/llui/llscrolllistitem.cpp index c490a5249..d6d3cf2aa 100644 --- a/indra/llui/llscrolllistitem.cpp +++ b/indra/llui/llscrolllistitem.cpp @@ -38,6 +38,7 @@ LLScrollListItem::LLScrollListItem( const Params& p ) : mSelected(FALSE), mEnabled(p.enabled), + mFiltered(false), mUserdata(p.userdata), mItemValue(p.value), mColumns() diff --git a/indra/llui/llscrolllistitem.h b/indra/llui/llscrolllistitem.h index a1229e034..f291b7cf2 100644 --- a/indra/llui/llscrolllistitem.h +++ b/indra/llui/llscrolllistitem.h @@ -71,6 +71,9 @@ public: void setEnabled( BOOL b ) { mEnabled = b; } BOOL getEnabled() const { return mEnabled; } + void setFiltered(bool b) { if (mFiltered = b) mSelected = false; } + bool getFiltered() const { return mFiltered; } + void setUserdata( void* userdata ) { mUserdata = userdata; } void* getUserdata() const { return mUserdata; } @@ -100,6 +103,7 @@ protected: private: BOOL mSelected; BOOL mEnabled; + bool mFiltered; void* mUserdata; LLSD mItemValue; std::vector mColumns; diff --git a/indra/llui/llspinctrl.cpp b/indra/llui/llspinctrl.cpp index 9c50c5402..57c9f3aa6 100644 --- a/indra/llui/llspinctrl.cpp +++ b/indra/llui/llspinctrl.cpp @@ -264,6 +264,7 @@ void LLSpinCtrl::forceSetValue(const LLSD& value ) mValue = v; updateEditor(); + mEditor->resetScrollPosition(); } } @@ -329,7 +330,9 @@ void LLSpinCtrl::onEditorCommit( const LLSD& data ) if( success ) { - updateEditor(); + // We committed and clamped value + // try to display as much as possible + mEditor->resetScrollPosition(); } else { @@ -461,6 +464,7 @@ BOOL LLSpinCtrl::handleKeyHere(KEY key, MASK mask) // text editors don't support revert normally (due to user confusion) // but not allowing revert on a spinner seems dangerous updateEditor(); + mEditor->resetScrollPosition(); mEditor->setFocus(FALSE); return TRUE; } diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp index b0572a070..2e1c70baf 100644 --- a/indra/llui/lltexteditor.cpp +++ b/indra/llui/lltexteditor.cpp @@ -386,9 +386,15 @@ const std::string& LLTextEditor::getMenuSegmentUrl() const static LLTextEditor* get_focused_text_editor() { - auto* list = dynamic_cast(gFocusMgr.getKeyboardFocus()); - llassert(list); // This listener only applies to lists - return list; + auto* te = +#ifdef SHOW_ASSERT + dynamic_cast +#else + static_cast +#endif + (gFocusMgr.getKeyboardFocus()); + llassert(te); // This listener only applies to text editors + return te; } class ContextText : public LLMemberListener @@ -436,20 +442,67 @@ class ContextUrl : public LLMemberListener } }; -class ContextUrlCopy : public LLMemberListener +class ContextIDUrl : public LLMemberListener { - - bool handleEvent(LLPointer, const LLSD& userdata) override +protected: + std::string getID(const std::string& type) const { const auto& url = get_focused_url(); - const auto& type = userdata.asStringRef(); // Empty works like avatar and group, "object" is an object (you needed to be told this) - const auto& id = type.empty() ? LLUrlAction::getUserID(url) : LLUrlAction::getObjectId(url); - LLView::getWindow()->copyTextToClipboard(utf8str_to_wstring(id)); + return type.empty() ? LLUrlAction::getUserID(url) : LLUrlAction::getObjectId(url); + } +}; + +class ContextUrlCopy : public ContextIDUrl +{ + bool handleEvent(LLPointer, const LLSD& userdata) override + { + LLView::getWindow()->copyTextToClipboard(utf8str_to_wstring(getID(userdata.asStringRef()))); return true; } }; +class ContextUrlExt : public ContextIDUrl +{ + bool handleEvent(LLPointer, const LLSD& userdata) override + { + std::string cmd = userdata.asStringRef(); + std::string type; + const auto sep = cmd.find(','); + if (sep != std::string::npos) + { + type = cmd.substr(sep); + cmd = cmd.substr(0, sep); + } + mExtCallback(cmd, LLUUID(getID(type))); + return true; + } + LLTextEditor::ext_slurl_cb mExtCallback; +public: + ContextUrlExt(LLTextEditor::ext_slurl_cb cb) : mExtCallback(cb) {} +}; + +class ContextUrlExtVisible : public ContextIDUrl +{ + bool handleEvent(LLPointer, const LLSD& userdata) override + { + std::string cmd = userdata["data"]; + std::string type; + const auto sep = cmd.find(','); + if (sep != std::string::npos) + { + type = cmd.substr(sep); + cmd = cmd.substr(0, sep); + } + + LLMenuGL::sMenuContainer->findControl(userdata["control"].asString())->setValue(mExtVCB(cmd, LLUUID(getID(type)))); + return true; + } + LLTextEditor::ext_slurl_visible_cb mExtVCB; +public: + ContextUrlExtVisible(LLTextEditor::ext_slurl_visible_cb vcb) : mExtVCB(vcb) {} +}; + void LLTextEditor::spell_correct(void* data) { @@ -528,11 +581,13 @@ void LLTextEditor::spell_add(void* data) } //static -void LLTextEditor::addMenuListeners() +void LLTextEditor::addMenuListeners(ext_slurl_cb cb, ext_slurl_visible_cb vcb) { (new ContextText)->registerListener(LLMenuGL::sMenuContainer, "Text"); (new ContextUrl)->registerListener(LLMenuGL::sMenuContainer, "Text.Url"); (new ContextUrlCopy)->registerListener(LLMenuGL::sMenuContainer, "Text.Url.CopyUUID"); + (new ContextUrlExt(cb))->registerListener(LLMenuGL::sMenuContainer, "Text.Url.Ext"); + (new ContextUrlExtVisible(vcb))->registerListener(LLMenuGL::sMenuContainer, "Text.Url.ExtVisible"); } void LLTextEditor::setTrackColor( const LLColor4& color ) @@ -721,8 +776,8 @@ LLMenuGL* LLTextEditor::createUrlContextMenu(S32 x, S32 y, const std::string &in if (addFriendButton && removeFriendButton) { - addFriendButton->setEnabled(!isFriend); - removeFriendButton->setEnabled(isFriend); + addFriendButton->setVisible(!isFriend); + removeFriendButton->setVisible(isFriend); } } diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h index c8a67fdbd..b5d3eb699 100644 --- a/indra/llui/lltexteditor.h +++ b/indra/llui/lltexteditor.h @@ -80,7 +80,11 @@ public: static boost::signals2::connection setIsFriendCallback(const is_friend_signal_t::slot_type& cb); static boost::signals2::connection setIsObjectBlockedCallback(const is_blocked_signal_t::slot_type& cb); - static void addMenuListeners(); + + typedef std::function ext_slurl_cb; + typedef std::function ext_slurl_visible_cb; + static void addMenuListeners(ext_slurl_cb cb, ext_slurl_visible_cb vcb); + void setKeystrokeCallback(const keystroke_signal_t::slot_type& callback); virtual LLXMLNodePtr getXML(bool save_children = true) const; diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp index 81be0e2de..a737c446f 100644 --- a/indra/llui/llurlentry.cpp +++ b/indra/llui/llurlentry.cpp @@ -1133,6 +1133,15 @@ std::string LLUrlEntryPlace::getLabel(const std::string &url, const LLUrlLabelCa std::string y = path_array[1]; return location + " (" + x + "," + y + ")"; } + else if (path_parts > 3) // xgrid, show as grid: place(x, y, z) + { + auto place = unescapeUrl(path_array[1].asStringRef()); + const auto& x = path_array[2].asStringRef(); + const auto& y = path_array[3].asStringRef(); + location += ": " + place + " (" + x + ',' + y; + if (path_parts == 5) location += ',' + path_array[4].asStringRef(); + return location + ')'; + } return url; } @@ -1140,6 +1149,12 @@ std::string LLUrlEntryPlace::getLabel(const std::string &url, const LLUrlLabelCa std::string LLUrlEntryPlace::getLocation(const std::string &url) const { // return the part of the Url after secondlife:// part + const auto uri = LLURI(url); + bool xgrid = boost::algorithm::starts_with(uri.scheme(), "x-grid"); + if (xgrid) + { + return ::getStringAfterToken(url, "region/"); + } return ::getStringAfterToken(url, "://"); } @@ -1149,7 +1164,7 @@ std::string LLUrlEntryPlace::getLocation(const std::string &url) const // LLUrlEntryRegion::LLUrlEntryRegion() { - mPattern = boost::regex("secondlife:///app/region/[^/\\s]+(/\\d+)?(/\\d+)?(/\\d+)?/?", + mPattern = boost::regex(X_GRID_OR_SECONDLIFE_HEADER_REGEX"//app/region/[^/\\s]+(/\\d+)?(/\\d+)?(/\\d+)?/?", boost::regex::perl|boost::regex::icase); mMenuName = "menu_url_slurl.xml"; mTooltip = LLTrans::getString("TooltipSLURL"); @@ -1165,30 +1180,37 @@ std::string LLUrlEntryRegion::getLabel(const std::string &url, const LLUrlLabelC // - secondlife:///app/region/Place // - LLSD path_array = LLURI(url).pathArray(); + const auto uri = LLURI(url); + LLSD path_array = uri.pathArray(); S32 path_parts = path_array.size(); - if (path_parts < 3) // no region name + bool xgrid = boost::algorithm::starts_with(uri.scheme(), "x-grid"); + auto i = xgrid ? 3 : 2; + + if (path_parts < i+1) // no region name { LL_WARNS() << "Failed to parse url [" << url << "]" << LL_ENDL; return url; } - std::string label = unescapeUrl(path_array[2]); // region name + std::string label = + xgrid ? unescapeUrl(path_array[0].asStringRef()) + ": " + unescapeUrl(path_array[i].asStringRef()) : // grid and region name + unescapeUrl(path_array[i].asStringRef()); // region name - if (path_parts > 3) // secondlife:///app/region/Place/X + ++i; + if (path_parts > i+1) // secondlife:///app/region/Place/X { - std::string x = path_array[3]; + std::string x = path_array[i++]; label += " (" + x; - if (path_parts > 4) // secondlife:///app/region/Place/X/Y + if (path_parts > i+1) // secondlife:///app/region/Place/X/Y { - std::string y = path_array[4]; + std::string y = path_array[i++]; label += "," + y; - if (path_parts > 5) // secondlife:///app/region/Place/X/Y/Z + if (path_parts > i+1) // secondlife:///app/region/Place/X/Y/Z { - std::string z = path_array[5]; + std::string z = path_array[i]; label = label + "," + z; } } @@ -1201,8 +1223,10 @@ std::string LLUrlEntryRegion::getLabel(const std::string &url, const LLUrlLabelC std::string LLUrlEntryRegion::getLocation(const std::string &url) const { - LLSD path_array = LLURI(url).pathArray(); - std::string region_name = unescapeUrl(path_array[2]); + const auto uri = LLURI(url); + LLSD path_array = uri.pathArray(); + bool xgrid = boost::algorithm::starts_with(uri.scheme(), "x-grid"); + std::string region_name = unescapeUrl(path_array[xgrid ? 3 : 2]); return region_name; } diff --git a/indra/llvfs/CMakeLists.txt b/indra/llvfs/CMakeLists.txt index 326f6671c..aa60e08dd 100644 --- a/indra/llvfs/CMakeLists.txt +++ b/indra/llvfs/CMakeLists.txt @@ -62,6 +62,8 @@ list(APPEND llvfs_SOURCE_FILES ${llvfs_HEADER_FILES}) add_library (llvfs ${llvfs_SOURCE_FILES}) target_link_libraries(llvfs + PUBLIC + llcommon ${Boost_FILESYSTEM_LIBRARY} ${Boost_SYSTEM_LIBRARY} ) diff --git a/indra/llvfs/lldir_linux.cpp b/indra/llvfs/lldir_linux.cpp index c1ae9eae1..6e70c2235 100644 --- a/indra/llvfs/lldir_linux.cpp +++ b/indra/llvfs/lldir_linux.cpp @@ -262,7 +262,7 @@ bool LLDir_Linux::fileExists(const std::string &filename) const /*virtual*/ std::string LLDir_Linux::getLLPluginLauncher() { return gDirUtilp->getExecutableDir() + gDirUtilp->getDirDelimiter() + - "SLPlugin"; + "llplugin/SLPlugin"; } /*virtual*/ std::string LLDir_Linux::getLLPluginFilename(std::string base_name) diff --git a/indra/llwindow/CMakeLists.txt b/indra/llwindow/CMakeLists.txt index 2a9396526..73a7aa59b 100644 --- a/indra/llwindow/CMakeLists.txt +++ b/indra/llwindow/CMakeLists.txt @@ -148,4 +148,4 @@ endif (llwindow_HEADER_FILES) ${viewer_SOURCE_FILES} ) -target_link_libraries (llwindow ${llwindow_LINK_LIBRARIES}) +target_link_libraries (llwindow PUBLIC llcommon ${llwindow_LINK_LIBRARIES}) diff --git a/indra/llwindow/llwindowsdl.cpp b/indra/llwindow/llwindowsdl.cpp index 79c8f8420..75aaf78ab 100644 --- a/indra/llwindow/llwindowsdl.cpp +++ b/indra/llwindow/llwindowsdl.cpp @@ -1385,18 +1385,25 @@ LLWindow::LLWindowResolution* LLWindowSDL::getSupportedResolutions(S32 &num_reso { modes--; SDL_Rect *r = *modes; - int w = r->w; - int h = r->h; + S32 w = r->w; + S32 h = r->h; if ((w >= 800) && (h >= 600)) { // make sure we don't add the same resolution multiple times! - if ( (mNumSupportedResolutions == 0) || - ((mSupportedResolutions[mNumSupportedResolutions-1].mWidth != w) && - (mSupportedResolutions[mNumSupportedResolutions-1].mHeight != h)) ) + bool resolution_exists = false; + for (S32 i = 0; i < mNumSupportedResolutions; ++i) + { + if (mSupportedResolutions[i].mWidth == w && + mSupportedResolutions[i].mHeight == h) + { + resolution_exists = true; + break; + } + } + if (!resolution_exists) { mSupportedResolutions[mNumSupportedResolutions].mWidth = w; - mSupportedResolutions[mNumSupportedResolutions].mHeight = h; - mNumSupportedResolutions++; + mSupportedResolutions[mNumSupportedResolutions++].mHeight = h; } } } diff --git a/indra/llxml/CMakeLists.txt b/indra/llxml/CMakeLists.txt index 2245255cd..576fb0ffe 100644 --- a/indra/llxml/CMakeLists.txt +++ b/indra/llxml/CMakeLists.txt @@ -40,5 +40,7 @@ add_library (llxml ${llxml_SOURCE_FILES}) target_link_libraries( llxml + PUBLIC + llcommon ${EXPAT_LIBRARIES} ) diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 5e2a26f10..bebccf1e2 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -3,13 +3,16 @@ project(viewer) include(00-Common) +# DON'T move Linking.cmake to its place in the alphabetized list below: it +# sets variables on which the 3p .cmake files depend. +include(Linking) + include(Boost) include(BuildPackagesInfo) include(BuildVersion) include(BuildBranding) include(CMakeCopyIfDifferent) include(DBusGlib) -include(FindVCRedist) include(FMODSTUDIO) include(GLOD) include(Hunspell) @@ -32,7 +35,6 @@ include(LLUI) include(LLVFS) include(LLWindow) include(LLXML) -include(Linking) include(NDOF) include(NVAPI) include(OPENAL) @@ -88,7 +90,6 @@ set(viewer_SOURCE_FILES daeexport.cpp floaterao.cpp floaterlocalassetbrowse.cpp - floatervoicelicense.cpp generichandlers.cpp groupchatlistener.cpp hbfloatergrouptitles.cpp @@ -185,6 +186,7 @@ set(viewer_SOURCE_FILES llfloateravatarlist.cpp llfloateravatarpicker.cpp llfloateravatartextures.cpp + llfloaterbanduration.cpp llfloaterbeacons.cpp llfloaterblacklist.cpp llfloaterbuildoptions.cpp @@ -625,7 +627,6 @@ set(viewer_HEADER_FILES daeexport.h floaterao.h floaterlocalassetbrowse.h - floatervoicelicense.h generichandlers.h groupchatlistener.h hbfloatergrouptitles.h @@ -722,6 +723,7 @@ set(viewer_HEADER_FILES llfloateravatarlist.h llfloateravatarpicker.h llfloateravatartextures.h + llfloaterbanduration.h llfloaterbeacons.h llfloaterblacklist.h llfloaterbuildoptions.h @@ -1519,7 +1521,7 @@ if (WINDOWS) ${ARCH_PREBUILT_DIRS_DEBUG}/libeay32.dll ${ARCH_PREBUILT_DIRS_DEBUG}/ssleay32.dll SLPlugin - media_plugin_quicktime + media_plugin_libvlc media_plugin_cef windows-crash-logger ) @@ -1581,29 +1583,6 @@ if (WINDOWS) add_custom_target(copy_w_viewer_manifest ALL DEPENDS ${CMAKE_CFG_INTDIR}/copy_touched.bat) - if(EXISTS ${VISUAL_STUDIO_REDISTRIBUTABLE_PATH}) - add_custom_command( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/redist - COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/redist" - DEPENDS copy_w_viewer_manifest - COMMENT "Creating redist dir" - ) - add_custom_command( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/redist/${VISUAL_STUDIO_REDISTRIBUTABLE_NAME} - COMMAND ${CMAKE_COMMAND} -E copy_if_different - ARGS - ${VISUAL_STUDIO_REDISTRIBUTABLE_PATH} - ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/redist/${VISUAL_STUDIO_REDISTRIBUTABLE_NAME} - DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/redist - COMMENT "Copying ${VISUAL_STUDIO_REDISTRIBUTABLE_PATH} to redist dir" - ) - - add_custom_target(copy_w_redist ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/redist/${VISUAL_STUDIO_REDISTRIBUTABLE_NAME}) - - add_dependencies(${VIEWER_BINARY_NAME} copy_w_redist) - endif() - - add_dependencies(${VIEWER_BINARY_NAME} stage_third_party_libs llcommon copy_w_viewer_manifest) if (EXISTS ${CMAKE_SOURCE_DIR}/copy_win_scripts) @@ -1704,6 +1683,8 @@ target_link_libraries(${VIEWER_BINARY_NAME} ${HUNSPELL_LIBRARY} ${LLPHYSICSEXTENSIONS_LIBRARIES} ${LLAPPEARANCE_LIBRARIES} + absl::flat_hash_map + absl::node_hash_map ) if (LINUX) @@ -1766,13 +1747,12 @@ if (LINUX) ) add_dependencies(${VIEWER_BINARY_NAME} SLPlugin media_plugin_gstreamer010 basic_plugin_filepicker) - add_custom_target(copy_l_viewer_manifest ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/.${product}.copy_touched) if (PACKAGE) add_custom_target(llpackage ALL DEPENDS ${product}.tar.xz) - # Make sure we don't run two instances of viewer_manifest.py at the same time. - add_dependencies(llpackage copy_l_viewer_manifest) check_message_template(llpackage) + else (PACKAGE) + add_custom_target(copy_l_viewer_manifest ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/.${product}.copy_touched) endif (PACKAGE) endif (LINUX) @@ -1822,7 +1802,7 @@ if (DARWIN) ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py ) - add_dependencies(${VIEWER_BINARY_NAME} SLPlugin media_plugin_quicktime media_plugin_webkit basic_plugin_filepicker) + add_dependencies(${VIEWER_BINARY_NAME} SLPlugin media_plugin_libvlc media_plugin_webkit basic_plugin_filepicker) if (PACKAGE) add_custom_target(llpackage ALL DEPENDS ${VIEWER_BINARY_NAME}) diff --git a/indra/newview/app_settings/keywords.ini b/indra/newview/app_settings/keywords.ini index a4a448ca8..3efc914cd 100644 --- a/indra/newview/app_settings/keywords.ini +++ b/indra/newview/app_settings/keywords.ini @@ -54,6 +54,9 @@ http_response http_response(key request_id, integer status, list metad http_request http_request(key id, string method, string body):Triggered when task receives an http request against a public URL transaction_result transaction_result(key id, integer success, string data): Triggered when currency is given to task path_update path_update(integer type, list reserved):Triggered when the state of a pathfinder character changes. Note; "list reserved" is not currently used +experience_permissions experience_permissions(key agent): Triggered when agent has approved an experience permissions request. This may be through interaction with the experience permission dialog or the experience profile, or automatically if the agent has previously approved the experience. +experience_permissions_denied experience_permissions_denied(key agent, integer reason): Triggered when agent has denied experience permission. reason is the reason for denial; one of the Experience Tools XP_ERROR_* errors flags. + # integer constants [word .1, .1, .5] @@ -65,11 +68,11 @@ STATUS_ROTATE_X Passed in the llSetStatus library function. If FALSE, o STATUS_ROTATE_Y Passed in the llSetStatus library function. If FALSE, object doesn't rotate around local Y axis STATUS_ROTATE_Z Passed in the llSetStatus library function. If FALSE, object doesn't rotate around local Z axis STATUS_SANDBOX Passed in the llSetStatus library function. If TRUE, object can't cross region boundaries or move more than 10 meters from its start location -STATUS_BLOCK_GRAB Passed in the llSetStatus library function. If TRUE, object can't be grabbed and physically dragged -STATUS_BLOCK_GRAB_OBJECT This status flag keeps the object from being moved by grabs. This flag applies to the entire linkset +STATUS_BLOCK_GRAB Passed in the llSetStatus library function. If TRUE, root prim of linkset (or unlinked prim) can't be grabbed and physically dragged STATUS_DIE_AT_EDGE Passed in the llSetStatus library function. If TRUE, objects that reach the edge of the world just die:rather than teleporting back to the owner STATUS_RETURN_AT_EDGE Passed in the llSetStatus library function. If TRUE, script rezzed objects that reach the edge of the world:are returned rather than killed:STATUS_RETURN_AT_EDGE trumps STATUS_DIE_AT_EDGE if both are set STATUS_CAST_SHADOWS Passed in the llSetStatus library function. If TRUE, object casts shadows on other objects +STATUS_BLOCK_GRAB_OBJECT Passed in the llSetStatus library function. If TRUE, no prims in linkset can be grabbed or physically dragged AGENT Passed in llSensor library function to look for other Agents; DEPRECATED: Use AGENT_BY_LEGACY_NAME AGENT_BY_LEGACY_NAME Passed in llSensor library function to look for other Agents by legacy name @@ -150,15 +153,6 @@ PSYS_PART_EMISSIVE_MASK PSYS_PART_TARGET_LINEAR_MASK PSYS_PART_RIBBON_MASK -PSYS_PART_BF_ONE -PSYS_PART_BF_ZERO -PSYS_PART_BF_DEST_COLOR -PSYS_PART_BF_SOURCE_COLOR -PSYS_PART_BF_ONE_MINUS_DEST_COLOR -PSYS_PART_BF_ONE_MINUS_SOURCE_COLOR -PSYS_PART_BF_SOURCE_ALPHA -PSYS_PART_BF_ONE_MINUS_SOURCE_ALPHA - PSYS_SRC_PATTERN PSYS_SRC_INNERANGLE Deprecated -- Use PSYS_SRC_ANGLE_BEGIN PSYS_SRC_OUTERANGLE Deprecated -- Use PSYS_SRC_ANGLE_END @@ -180,6 +174,14 @@ PSYS_SRC_PATTERN_EXPLODE PSYS_SRC_PATTERN_ANGLE PSYS_SRC_PATTERN_ANGLE_CONE PSYS_SRC_PATTERN_ANGLE_CONE_EMPTY +PSYS_PART_BF_ONE +PSYS_PART_BF_ZERO +PSYS_PART_BF_DEST_COLOR +PSYS_PART_BF_SOURCE_COLOR +PSYS_PART_BF_ONE_MINUS_DEST_COLOR +PSYS_PART_BF_ONE_MINUS_SOURCE_COLOR +PSYS_PART_BF_SOURCE_ALPHA +PSYS_PART_BF_ONE_MINUS_SOURCE_ALPHA OBJECT_UNKNOWN_DETAIL Returned by llGetObjectDetails when passed an invalid object parameter type OBJECT_HOVER_HEIGHT This is a flag used with llGetObjectDetails to get hover height of the avatar. If no data is available, 0.0 is returned. @@ -404,8 +406,6 @@ REMOTE_DATA_REQUEST Value of event_type in remote_event if X REMOTE_DATA_REPLY Value of event_type in remote_event if XML-RPC reply is received -PRIM_NAME Sets the prim's name -PRIM_DESC Sets the prim's description PRIM_TYPE Followed by PRIM_TYPE_BOX, PRIM_TYPE_CYLINDER, PRIM_TYPE_PRISM, PRIM_TYPE_SPHERE, PRIM_TYPE_TORUS, PRIM_TYPE_TUBE, or PRIM_TYPE_SCULPT and their arguments PRIM_MATERIAL Followed by PRIM_MATERIAL_STONE, PRIM_MATERIAL_METAL, PRIM_MATERIAL_GLASS, PRIM_MATERIAL_WOOD, PRIM_MATERIAL_FLESH, PRIM_MATERIAL_PLASTIC, or PRIM_MATERIAL_RUBBER PRIM_PHYSICS Sets physics to TRUE or FALSE @@ -417,19 +417,26 @@ PRIM_CAST_SHADOWS DEPRECATED. Takes 1 parameter, an intege PRIM_POSITION Sets primitive position to a vector position PRIM_SIZE Sets primitive size to a vector size PRIM_ROTATION Sets primitive rotation -PRIM_TEXT Used to get or set the object's floating text. PRIM_TEXTURE Followed by an integer face, key id, vector repeats, vector offsets,:and float rotation in radians PRIM_COLOR Followed by an integer face, vector color, and float alpha PRIM_BUMP_SHINY Followed by an integer face, one of PRIM_SHINY_NONE, PRIM_SHINY_LOW,:PRIM_SHINY_MEDIUM, or PRIM_SHINY_HIGH,:and one of PRIM_BUMP_NONE, PRIM_BUMP_BRIGHT, PRIM_BUMP_DARK, etc PRIM_FULLBRIGHT Followed by an integer face, and TRUE or FALSE PRIM_TEXGEN Followed by an integer face, and one of PRIM_TEXGEN_DEFAULT or PRIM_TEXGEN_PLANAR PRIM_GLOW Followed by an integer face, and a float from 0.0 to 1.0 specifying glow amount -PRIM_POS_LOCAL Sets the prim's local position +PRIM_TEXT Used to get or set the object's floating text. +PRIM_NAME Sets the prim's name +PRIM_DESC Sets the prim's description PRIM_ROT_LOCAL Sets the prim's local rotation +PRIM_PHYSICS_SHAPE_TYPE For primitive physics shape type. Followed with either PRIM_PHYSICS_SHAPE_PRIM, PRIM_PHYSICS_SHAPE_NONE or PRIM_PHYSICS_SHAPE_CONVEX. PRIM_OMEGA Makes the object spin at the specified axis and rate +PRIM_POS_LOCAL Sets the prim's local position PRIM_LINK_TARGET Used to get or set multiple links with a single PrimParameters call. PRIM_SLICE Get and set the 'slice' parameter of all shapes. Takes a vector parameter of the form +PRIM_PHYSICS_SHAPE_PRIM Use the normal prim shape for physics (this is the default for all non-mesh objects) +PRIM_PHYSICS_SHAPE_NONE Use the convex hull of the prim shape for physics (this is the default for mesh objects) +PRIM_PHYSICS_SHAPE_CONVEX Ignore this prim in the physics shape. This cannot be applied to the root prim. + PRIM_TYPE_BOX Followed by integer hole shape, vector cut, float hollow, vector twist,:vector top size, and vector top shear PRIM_TYPE_CYLINDER Followed by integer hole shape, vector cut, float hollow, vector twist,:vector top size, and vector top shear PRIM_TYPE_PRISM Followed by integer hole shape, vector cut, float hollow, vector twist,:vector top size, and vector top shear @@ -489,11 +496,6 @@ PRIM_SCULPT_TYPE_MASK Mask used to determine stitching type PRIM_SCULPT_FLAG_INVERT Flag to specify that the surface normals should be inverted PRIM_SCULPT_FLAG_MIRROR Flag to specify that the prim should be reflected along X axis -PRIM_PHYSICS_SHAPE_TYPE For primitive physics shape type. Followed with either PRIM_PHYSICS_SHAPE_PRIM, PRIM_PHYSICS_SHAPE_NONE or PRIM_PHYSICS_SHAPE_CONVEX. -PRIM_PHYSICS_SHAPE_PRIM Use the normal prim shape for physics (this is the default for all non-mesh objects) -PRIM_PHYSICS_SHAPE_NONE Use the convex hull of the prim shape for physics (this is the default for mesh objects) -PRIM_PHYSICS_SHAPE_CONVEX Ignore this prim in the physics shape. This cannot be applied to the root prim. - PRIM_SPECULAR Used to get or set the specular map texture settings of a prim's face. PRIM_NORMAL Used to get or set the normal map texture settings of a prim's face. @@ -519,7 +521,7 @@ PARCEL_MEDIA_COMMAND_STOP Stop media stream PARCEL_MEDIA_COMMAND_PAUSE Pause media stream PARCEL_MEDIA_COMMAND_PLAY Play media stream PARCEL_MEDIA_COMMAND_LOOP Loop media stream -PARCEL_MEDIA_COMMAND_LOOP_SET Used to get or set the parcel's media loop duration +PARCEL_MEDIA_COMMAND_LOOP_SET Used to get or set the parcel's media loop duration. PARCEL_MEDIA_COMMAND_TEXTURE Get or set the parcel's media texture PARCEL_MEDIA_COMMAND_URL Get or set the parcel's media url PARCEL_MEDIA_COMMAND_TYPE Get or set the parcel's media mimetype @@ -672,12 +674,12 @@ RCERR_CAST_TIME_EXCEEDED Returned by llCastRay() when the raycast f RCERR_SIM_PERF_LOW Returned by llCastRay() when the raycast failed because simulator performance is low. RCERR_UNKNOWN Returned by llCastRay() when the raycast failed for an unspecified reason. -ESTATE_ACCESS_ALLOWED_AGENT_ADD Used with llManageEstateAccess to add an agent to this estate's allowed residents list. -ESTATE_ACCESS_ALLOWED_AGENT_REMOVE Used with llManageEstateAccess to remove an agent from this estate's allowed residents list. -ESTATE_ACCESS_ALLOWED_GROUP_ADD Used with llManageEstateAccess to add a group to this estate's allowed groups list. -ESTATE_ACCESS_ALLOWED_GROUP_REMOVE Used with llManageEstateAccess to remove a group from this estate's allowed groups list. -ESTATE_ACCESS_BANNED_AGENT_ADD Used with llManageEstateAccess to add an agent to this estate's banned residents list. -ESTATE_ACCESS_BANNED_AGENT_REMOVE Used with llManageEstateAccess to remove an agent from this estate's banned residents list. +ESTATE_ACCESS_ALLOWED_AGENT_ADD Passed to llManageEstateAccess to add the agent to this estate's Allowed Residents list +ESTATE_ACCESS_ALLOWED_AGENT_REMOVE Passed to llManageEstateAccess to remove the agent from this estate's Allowed Residents list +ESTATE_ACCESS_ALLOWED_GROUP_ADD Passed to llManageEstateAccess to add the group to this estate's Allowed groups list +ESTATE_ACCESS_ALLOWED_GROUP_REMOVE Passed to llManageEstateAccess to remove the group from this estate's Allowed groups list +ESTATE_ACCESS_BANNED_AGENT_ADD Passed to llManageEstateAccess to add the agent to this estate's Banned residents list +ESTATE_ACCESS_BANNED_AGENT_REMOVE Passed to llManageEstateAccess to remove the agent from this estate's Banned residents list DENSITY For use with llSetPhysicsMaterial() as a bitwise value in its material_bits parameter, to set the density. FRICTION For use with llSetPhysicsMaterial() as a bitwise value in its material_bits parameter, to set the friction. @@ -690,6 +692,7 @@ KFM_COMMAND Option for llSetKeyframedMotion(), followe KFM_CMD_PLAY Option for llSetKeyframedMotion(), used after KFM_COMMAND to play the motion. KFM_CMD_STOP Option for llSetKeyframedMotion(), used after KFM_COMMAND to stop the motion. KFM_CMD_PAUSE Option for llSetKeyframedMotion(), used after KFM_COMMAND to pause the motion. +#KFM_CMD_SET_MODE TODO: add documentation KFM_MODE Option for llSetKeyframedMotion(), used to specify the playback mode, followed by one of KFM_FORWARD, KFM_LOOP, KFM_PING_PONG or KFM_REVERSE. KFM_FORWARD Option for llSetKeyframedMotion(), used after KFM_MODE to specify the forward playback mode. KFM_LOOP Option for llSetKeyframedMotion(), used after KFM_MODE to specify the loop playback mode. @@ -735,7 +738,7 @@ PU_FAILURE_NO_NAVMESH Triggered if no navmesh is available for the re PU_FAILURE_DYNAMIC_PATHFINDING_DISABLED Triggered when a character enters a region with dynamic pathfinding disabled. PU_FAILURE_PARCEL_UNREACHABLE Triggered when a character failed to enter a parcel because it is not allowed to enter, e.g. because the parcel is already full or because object entry was disabled after the navmesh was baked. -CHARACTER_TYPE Specifies which walkability coefficient will be used by this character. +CHARACTER_TYPE Specifies which walkability coefficient will be used by this character. Used in combination with one of the character type flags. CHARACTER_TYPE_A Used for character types that you prefer move in a way consistent with humanoids. CHARACTER_TYPE_B Used for character types that you prefer move in a way consistent with wild animals or off road vehicles. CHARACTER_TYPE_C Used for mechanical character types or road going vehicles. @@ -920,6 +923,26 @@ TEXTURE_TRANSPARENT UUID for the "White - Transparent" texture URL_REQUEST_GRANTED Used with http_request when a public URL is successfully granted URL_REQUEST_DENIED Used with http_request when a public URL is not available +XP_ERROR_NONE No error was detected +XP_ERROR_THROTTLED The call failed due to too many recent calls. +XP_ERROR_EXPERIENCES_DISABLED The region currently has experiences disabled. +XP_ERROR_INVALID_PARAMETERS One of the string arguments was too big to fit in the key-value store. +XP_ERROR_NOT_PERMITTED This experience is not allowed to run on the current region. +XP_ERROR_NO_EXPERIENCE This script is not associated with an experience. +XP_ERROR_NOT_FOUND The sim was unable to verify the validity of the experience. Retrying after a short wait is advised. +XP_ERROR_INVALID_EXPERIENCE The script is associated with an experience that no longer exists. +XP_ERROR_EXPERIENCE_DISABLED The experience owner has temporarily disabled the experience. +XP_ERROR_EXPERIENCE_SUSPENDED The experience has been suspended by Linden Customer Support. +XP_ERROR_QUOTA_EXCEEDED An attempted write data to the key-value store failed due to the data quota being met. +XP_ERROR_STORE_DISABLED The key-value store is currently disabled on this region. +XP_ERROR_STORAGE_EXCEPTION Unable to communicate with the key-value store. +XP_ERROR_KEY_NOT_FOUND The requested key does not exist. +XP_ERROR_RETRY_UPDATE A checked update failed due to an out of date request. +XP_ERROR_MATURITY_EXCEEDED The request failed due to agent content preferences. +XP_ERROR_UNKNOWN_ERROR Other unknown error. +XP_ERROR_INVALID_PARAMETERS One of the string arguments was too big to fit in the key-value store. + + # float constants [word .3, .1, .5] PI 3.1415926535897932384626433832795 diff --git a/indra/newview/app_settings/mime_types.xml b/indra/newview/app_settings/mime_types.xml index 61067da06..0f78823b3 100644 --- a/indra/newview/app_settings/mime_types.xml +++ b/indra/newview/app_settings/mime_types.xml @@ -7,7 +7,7 @@ none - media_plugin_webkit + media_plugin_cef + + + + none/none + + + icn_media_web.tga + + + No media here + + + + false + + + false + + - + + + + movie + + + media_plugin_libvlc + + + @@ -120,7 +152,7 @@ none - media_plugin_webkit + media_plugin_cef @@ -131,7 +163,7 @@ none - media_plugin_webkit + media_plugin_cef @@ -142,7 +174,7 @@ audio - media_plugin_quicktime + media_plugin_libvlc @@ -153,7 +185,7 @@ movie - media_plugin_quicktime + media_plugin_libvlc @@ -164,7 +196,7 @@ image - media_plugin_webkit + media_plugin_cef @@ -175,8 +207,8 @@ movie - media_plugin_quicktime - + media_plugin_libvlc + @@ -197,7 +229,7 @@ audio - media_plugin_quicktime + media_plugin_cef @@ -208,7 +240,7 @@ image - media_plugin_webkit + media_plugin_cef @@ -219,7 +251,7 @@ image - media_plugin_webkit + media_plugin_cef @@ -230,18 +262,18 @@ image - media_plugin_webkit + media_plugin_cef movie - media_plugin_webkit + media_plugin_cef @@ -252,7 +284,7 @@ web - media_plugin_webkit + media_plugin_cef @@ -263,7 +295,7 @@ image - media_plugin_webkit + media_plugin_cef @@ -274,7 +306,7 @@ audio - media_plugin_quicktime + media_plugin_cef @@ -285,7 +317,7 @@ audio - media_plugin_quicktime + media_plugin_libvlc @@ -296,7 +328,7 @@ audio - media_plugin_quicktime + media_plugin_libvlc @@ -307,7 +339,7 @@ audio - media_plugin_quicktime + media_plugin_libvlc @@ -318,7 +350,7 @@ image - media_plugin_webkit + media_plugin_cef @@ -329,7 +361,7 @@ image - media_plugin_webkit + media_plugin_cef @@ -340,7 +372,7 @@ image - media_plugin_webkit + media_plugin_cef @@ -351,7 +383,7 @@ image - media_plugin_webkit + media_plugin_cef @@ -362,7 +394,7 @@ image - media_plugin_webkit + media_plugin_cef @@ -373,7 +405,7 @@ image - media_plugin_webkit + media_plugin_cef @@ -384,8 +416,8 @@ web - media_plugin_webkit - + media_plugin_cef + @@ -406,7 +438,7 @@ text - media_plugin_webkit + media_plugin_cef @@ -417,8 +449,8 @@ movie - media_plugin_quicktime - + media_plugin_libvlc + + + + + movie + + + media_plugin_libvlc - - FloaterAboutRect @@ -7608,22 +7608,6 @@ This should be as low as possible, but too low may break functionality 0 - FloaterInvPanelRect - - Comment - Rectangle for new inventory windows a folder is opened in - Persist - 1 - Type - Rect - Value - - 0 - 400 - 300 - 0 - - FloaterJoystickRect Comment @@ -12701,11 +12685,11 @@ This should be as low as possible, but too low may break functionality AlwaysRenderFriends Comment - Always render friends regardless of max complexity + Always render friends regardless of max complexity, a value of 2 will only render friends Persist 1 Type - Boolean + S32 Value 0 @@ -17883,17 +17867,6 @@ This should be as low as possible, but too low may break functionality Value 1 - WarnQuickTimeInstalled - - Comment - Enables QuickTimeInstalled warning dialog - Persist - 1 - Type - Boolean - Value - 1 - WarnReturnToOwner Comment diff --git a/indra/newview/app_settings/settings_ascent.xml b/indra/newview/app_settings/settings_ascent.xml index 5c2f1ea63..65398b513 100644 --- a/indra/newview/app_settings/settings_ascent.xml +++ b/indra/newview/app_settings/settings_ascent.xml @@ -943,6 +943,17 @@ Changing this setting only affects new text. Value 1 + SupportChatDisplayBuild + + Comment + Whether or not to display your current build (and its channel indicator) when you speak in identified support group chats + Persist + 1 + Type + S32 + Value + -1 + WarnRecommendedUpdate Comment @@ -1779,6 +1790,19 @@ Changing this setting only affects new text. IsCOA 1 + ToolbarVisibleInventoryReceivedItems + + Comment + Whether or not the button for received items is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + IsCOA + 1 + ToolbarVisibleJoystick Comment @@ -1805,6 +1829,19 @@ Changing this setting only affects new text. IsCOA 1 + ToolbarVisibleMarketplace + + Comment + Whether or not the button for marketplace is on the toolbar + Persist + 1 + Type + Boolean + Value + 0 + IsCOA + 1 + ToolbarVisibleMarketplaceListings Comment diff --git a/indra/newview/app_settings/windlight/postprocesseffects.xml b/indra/newview/app_settings/windlight/postprocesseffects.xml index bf917ab33..afabea4aa 100644 --- a/indra/newview/app_settings/windlight/postprocesseffects.xml +++ b/indra/newview/app_settings/windlight/postprocesseffects.xml @@ -1,5 +1,5 @@ - + Asi Weird bloom_strength @@ -210,1059 +210,1617 @@ vignette_chromatic_aberration 0.01 - PyFX CatVision v1 - - bloom_strength - 1.5 - bloom_width - 2.25 - blur_strength - 30 - brightness - 4 - brightness_multiplier - 3 - contrast - 3 - contrast_base - - 1 - 0 - 0.25 - 1 - - enable_bloom - 0 - enable_color_filter - 1 - enable_gauss_blur - 1 - enable_motionblur - 1 - enable_night_vision - 0 - enable_posterize - 0 - enable_vignette - 1 - extract_high - 1 - extract_low - 0.949999999999999955591079 - gamma - 2 - gauss_blur_passes - 1 - noise_size - 25 - noise_strength - 0.4000000000000000222044605 - posterize_layers - 10 - saturation - 0.0499999523162841796875 - vignette_chromatic_aberration - 0.1000000014901161193847656 - vignette_darkness - 1 - vignette_desaturation - 1 - vignette_radius - 3.9999997615814208984375 - vignette_strength - 1 - - PyFX CatVision v1 Dark - - bloom_strength - 1.5 - bloom_width - 2.25 - blur_strength - 30 - brightness - 2 - brightness_multiplier - 3 - contrast - 3 - contrast_base - - 1 - 0 - 0.25 - 1 - - enable_bloom - 0 - enable_color_filter - 1 - enable_gauss_blur - 1 - enable_motionblur - 1 - enable_night_vision - 0 - enable_posterize - 0 - enable_vignette - 1 - extract_high - 1 - extract_low - 0.949999999999999955591079 - gamma - 2.5 - gauss_blur_passes - 1 - noise_size - 25 - noise_strength - 0.4000000000000000222044605 - posterize_layers - 10 - saturation - 0.0499999523162841796875 - vignette_chromatic_aberration - 0.1000000014901161193847656 - vignette_darkness - 1 - vignette_desaturation - 1 - vignette_radius - 3.9999997615814208984375 - vignette_strength - 1 - - PyFX GrimDark v1 - - bloom_strength - 1.5 - bloom_width - 2.25 - blur_strength - 15 - brightness - 4 - brightness_multiplier - 1 - contrast - 1.25 - contrast_base - - 0.699999988079071044921875 - 0.7999999523162841796875 - 1 - 1 - - enable_bloom - 0 - enable_color_filter - 1 - enable_gauss_blur - 0 - enable_motionblur - 1 - enable_night_vision - 0 - enable_posterize - 0 - enable_vignette - 1 - extract_high - 1 - extract_low - 0.949999999999999955591079 - gamma - 1.25 - gauss_blur_passes - 2 - noise_size - 52.5 - noise_strength - 0.4000000000000000222044605 - posterize_layers - 10 - saturation - 0.5 - vignette_chromatic_aberration - 0.009500000625848770141601563 - vignette_darkness - 1 - vignette_desaturation - 0 - vignette_radius - 2 - vignette_strength - 1 - - PyFX GrimDark v2 - - bloom_strength - 1.5 - bloom_width - 2.25 - blur_strength - 30 - brightness - 4 - brightness_multiplier - 3 - contrast - 1 - contrast_base - - 1 - 1 - 1 - 1 - - enable_bloom - 0 - enable_color_filter - 1 - enable_gauss_blur - 0 - enable_motionblur - 1 - enable_night_vision - 0 - enable_posterize - 0 - enable_vignette - 1 - extract_high - 1 - extract_low - 0.949999999999999955591079 - gamma - 1 - gauss_blur_passes - 2 - noise_size - 25 - noise_strength - 0.4000000000000000222044605 - posterize_layers - 10 - saturation - 0.599999904632568359375 - vignette_chromatic_aberration - 0.009500000625848770141601563 - vignette_darkness - 1 - vignette_desaturation - 0.4000000059604644775390625 - vignette_radius - 2.9999997615814208984375 - vignette_strength - 1 - - PyFX Memory v1 - - bloom_strength - 1.5 - bloom_width - 2.25 - blur_strength - 30 - brightness - 1.5 - brightness_multiplier - 3 - contrast - 1.25 - contrast_base - - 0 - 0.66999995708465576171875 - 1 - 1 - - enable_bloom - 0 - enable_color_filter - 1 - enable_gauss_blur - 0 - enable_motionblur - 1 - enable_night_vision - 0 - enable_posterize - 0 - enable_vignette - 1 - extract_high - 1 - extract_low - 0.949999999999999955591079 - gamma - 1.5 - gauss_blur_passes - 2 - noise_size - 25 - noise_strength - 0.4000000000000000222044605 - posterize_layers - 10 - saturation - 0.5 - vignette_chromatic_aberration - 0.005000000353902578353881836 - vignette_darkness - 1 - vignette_desaturation - 0.4000000059604644775390625 - vignette_radius - 5 - vignette_strength - 1 - - PyFX Memory v1 Cold - - bloom_strength - 1.5 - bloom_width - 2.25 - blur_strength - 30 - brightness - 1.5 - brightness_multiplier - 3 - contrast - 1.25 - contrast_base - - 1 - 0.329999983310699462890625 - 0 - 1 - - enable_bloom - 0 - enable_color_filter - 1 - enable_gauss_blur - 0 - enable_motionblur - 1 - enable_night_vision - 0 - enable_posterize - 0 - enable_vignette - 1 - extract_high - 1 - extract_low - 0.949999999999999955591079 - gamma - 1.5 - gauss_blur_passes - 2 - noise_size - 25 - noise_strength - 0.4000000000000000222044605 - posterize_layers - 10 - saturation - 0.5 - vignette_chromatic_aberration - 0.005000000353902578353881836 - vignette_darkness - 1 - vignette_desaturation - 0.4000000059604644775390625 - vignette_radius - 5 - vignette_strength - 1 - - PyFX Mono v1 - - bloom_strength - 1.5 - bloom_width - 2.25 - blur_strength - 30 - brightness - 1 - brightness_multiplier - 3 - contrast - 4 - contrast_base - - 1 - 1 - 1 - 0 - - enable_bloom - 0 - enable_color_filter - 1 - enable_gauss_blur - 0 - enable_motionblur - 1 - enable_night_vision - 0 - enable_posterize - 1 - enable_vignette - 1 - extract_high - 1 - extract_low - 0.949999999999999955591079 - gamma - 1 - gauss_blur_passes - 1 - noise_size - 25 - noise_strength - 0.4000000000000000222044605 - posterize_layers - 3 - saturation - 0 - vignette_chromatic_aberration - 0 - vignette_darkness - 1 - vignette_desaturation - 1 - vignette_radius - 1 - vignette_strength - 1 - - PyFX Neo v1 - - bloom_strength - 1.5 - bloom_width - 2.25 - blur_strength - 15 - brightness - 1.5 - brightness_multiplier - 1 - contrast - 1.25 - contrast_base - - 1 - 1 - 0.75 - 1 - - enable_bloom - 0 - enable_color_filter - 1 - enable_gauss_blur - 0 - enable_motionblur - 1 - enable_night_vision - 0 - enable_posterize - 0 - enable_vignette - 1 - extract_high - 1 - extract_low - 0.949999999999999955591079 - gamma - 1.25 - gauss_blur_passes - 2 - noise_size - 52.5 - noise_strength - 0.4000000000000000222044605 - posterize_layers - 10 - saturation - 0.849999904632568359375 - vignette_chromatic_aberration - 0.009500000625848770141601563 - vignette_darkness - 1 - vignette_desaturation - 0 - vignette_radius - 2 - vignette_strength - 1 - - PyFX Neo v1 Bright - - bloom_strength - 1.5 - bloom_width - 2.25 - blur_strength - 15 - brightness - 2.5 - brightness_multiplier - 1 - contrast - 1.25 - contrast_base - - 1 - 1 - 0.75 - 1 - - enable_bloom - 0 - enable_color_filter - 1 - enable_gauss_blur - 0 - enable_motionblur - 1 - enable_night_vision - 0 - enable_posterize - 0 - enable_vignette - 1 - extract_high - 1 - extract_low - 0.949999999999999955591079 - gamma - 1.25 - gauss_blur_passes - 2 - noise_size - 52.5 - noise_strength - 0.4000000000000000222044605 - posterize_layers - 10 - saturation - 0.849999904632568359375 - vignette_chromatic_aberration - 0.009500000625848770141601563 - vignette_darkness - 1 - vignette_desaturation - 0 - vignette_radius - 2 - vignette_strength - 1 - - PyFX Twilight v1 Cold - - bloom_strength - 1.5 - bloom_width - 2.25 - blur_strength - 30 - brightness - 1.25 - brightness_multiplier - 3 - contrast - 1.0299999713897705078125 - contrast_base - - 1 - 0.329999983310699462890625 - 0 - 1 - - enable_bloom - 0 - enable_color_filter - 1 - enable_gauss_blur - 0 - enable_motionblur - 1 - enable_night_vision - 0 - enable_posterize - 0 - enable_vignette - 1 - extract_high - 1 - extract_low - 0.949999999999999955591079 - gamma - 1.5 - gauss_blur_passes - 2 - noise_size - 25 - noise_strength - 0.4000000000000000222044605 - posterize_layers - 10 - saturation - 0.5 - vignette_chromatic_aberration - 0.005000000353902578353881836 - vignette_darkness - 1 - vignette_desaturation - 0.4000000059604644775390625 - vignette_radius - 5 - vignette_strength - 1 - - PyFX Twilight v1 Warm - - bloom_strength - 1.5 - bloom_width - 2.25 - blur_strength - 30 - brightness - 1.25 - brightness_multiplier - 3 - contrast - 1.0299999713897705078125 - contrast_base - - 0 - 0.66999995708465576171875 - 1 - 1 - - enable_bloom - 0 - enable_color_filter - 1 - enable_gauss_blur - 0 - enable_motionblur - 1 - enable_night_vision - 0 - enable_posterize - 0 - enable_vignette - 1 - extract_high - 1 - extract_low - 0.949999999999999955591079 - gamma - 1.5 - gauss_blur_passes - 2 - noise_size - 25 - noise_strength - 0.4000000000000000222044605 - posterize_layers - 10 - saturation - 0.5 - vignette_chromatic_aberration - 0.005000000353902578353881836 - vignette_darkness - 1 - vignette_desaturation - 0.4000000059604644775390625 - vignette_radius - 5 - vignette_strength - 1 - - PyFX Vivid v1 - - bloom_strength - 1.5 - bloom_width - 2.25 - blur_strength - 30 - brightness - 1.19999992847442626953125 - brightness_multiplier - 3 - contrast - 1.25 - contrast_base - - 0.7999999523162841796875 - 0.89999997615814208984375 - 1 - 1 - - enable_bloom - 0 - enable_color_filter - 1 - enable_gauss_blur - 0 - enable_motionblur - 1 - enable_night_vision - 0 - enable_posterize - 0 - enable_vignette - 1 - extract_high - 1 - extract_low - 0.949999999999999955591079 - gamma - 2 - gauss_blur_passes - 2 - noise_size - 25 - noise_strength - 0.4000000000000000222044605 - posterize_layers - 10 - saturation - 1.19999980926513671875 - vignette_chromatic_aberration - 0.004500000271946191787719727 - vignette_darkness - 1 - vignette_desaturation - 0 - vignette_radius - 2.9999997615814208984375 - vignette_strength - 1 - - PyFX Vivid v1 Cold - - bloom_strength - 1.5 - bloom_width - 2.25 - blur_strength - 30 - brightness - 1.19999992847442626953125 - brightness_multiplier - 3 - contrast - 1.25 - contrast_base - - 1 - 0.89999997615814208984375 - 0.7999999523162841796875 - 1 - - enable_bloom - 0 - enable_color_filter - 1 - enable_gauss_blur - 0 - enable_motionblur - 1 - enable_night_vision - 0 - enable_posterize - 0 - enable_vignette - 1 - extract_high - 1 - extract_low - 0.949999999999999955591079 - gamma - 2 - gauss_blur_passes - 2 - noise_size - 25 - noise_strength - 0.4000000000000000222044605 - posterize_layers - 10 - saturation - 1.19999980926513671875 - vignette_chromatic_aberration - 0.004500000271946191787719727 - vignette_darkness - 1 - vignette_desaturation - 0 - vignette_radius - 2.9999997615814208984375 - vignette_strength - 1 - - PyFX v1 - - bloom_strength - 1.5 - bloom_width - 2.25 - blur_strength - 30 - brightness - 1.19999992847442626953125 - brightness_multiplier - 3 - contrast - 1.25 - contrast_base - - 0.7999999523162841796875 - 0.89999997615814208984375 - 1 - 1 - - enable_bloom - 0 - enable_color_filter - 1 - enable_gauss_blur - 0 - enable_motionblur - 1 - enable_night_vision - 0 - enable_posterize - 0 - enable_vignette - 1 - extract_high - 1 - extract_low - 0.949999999999999955591079 - gamma - 2 - gauss_blur_passes - 2 - noise_size - 25 - noise_strength - 0.4000000000000000222044605 - posterize_layers - 10 - saturation - 0.7999999523162841796875 - vignette_chromatic_aberration - 0.004500000271946191787719727 - vignette_darkness - 1 - vignette_desaturation - 0 - vignette_radius - 1.5 - vignette_strength - 1 - - PyFX v2 - - bloom_strength - 1.5 - bloom_width - 2.25 - blur_strength - 30 - brightness - 1 - brightness_multiplier - 3 - contrast - 2 - contrast_base - - 0.949999988079071044921875 - 0.969999969005584716796875 - 1 - 1 - - enable_bloom - 1 - enable_color_filter - 1 - enable_gauss_blur - 0 - enable_motionblur - 1 - enable_night_vision - 0 - enable_posterize - 0 - enable_vignette - 1 - extract_high - 1 - extract_low - 0.949999999999999955591079 - gamma - 5 - gauss_blur_passes - 2 - noise_size - 25 - noise_strength - 0.4000000000000000222044605 - posterize_layers - 10 - saturation - 1 - vignette_chromatic_aberration - 0.004500000271946191787719727 - vignette_darkness - 1 - vignette_desaturation - 0 - vignette_radius - 1.5 - vignette_strength - 1 - - PyFX v3 - - bloom_strength - 1.5 - bloom_width - 2.25 - blur_strength - 30 - brightness - 1 - brightness_multiplier - 3 - contrast - 1.75 - contrast_base - - 0.949999988079071044921875 - 0.969999969005584716796875 - 1 - 1 - - enable_bloom - 1 - enable_color_filter - 1 - enable_gauss_blur - 0 - enable_motionblur - 1 - enable_night_vision - 0 - enable_posterize - 0 - enable_vignette - 1 - extract_high - 1 - extract_low - 0.949999999999999955591079 - gamma - 4 - gauss_blur_passes - 2 - noise_size - 25 - noise_strength - 0.4000000000000000222044605 - posterize_layers - 10 - saturation - 1.099999904632568359375 - vignette_chromatic_aberration - 0.004500000271946191787719727 - vignette_darkness - 0.66999995708465576171875 - vignette_desaturation - 0 - vignette_radius - 2.9999997615814208984375 - vignette_strength - 1 - - PyFX Default - - bloom_strength - 1.5 - bloom_width - 2.25 - blur_strength - 30 - brightness - 1 - brightness_multiplier - 3 - contrast - 1.75 - contrast_base - - 0.949999988079071044921875 - 0.969999969005584716796875 - 1 - 1 - - enable_bloom - 1 - enable_color_filter - 1 - enable_gauss_blur - 0 - enable_motionblur - 1 - enable_night_vision - 0 - enable_posterize - 0 - enable_vignette - 1 - extract_high - 1 - extract_low - 0.949999999999999955591079 - gamma - 4 - gauss_blur_passes - 2 - noise_size - 25 - noise_strength - 0.4000000000000000222044605 - posterize_layers - 10 - saturation - 1.099999904632568359375 - vignette_chromatic_aberration - 0.004500000271946191787719727 - vignette_darkness - 0.66999995708465576171875 - vignette_desaturation - 0 - vignette_radius - 2.9999997615814208984375 - vignette_strength - 1 - - + PyFX CatVision v1 + + bloom_strength + 1.5 + bloom_width + 2.25 + blur_strength + 30 + brightness + 4 + brightness_multiplier + 3 + contrast + 3 + contrast_base + + 1 + 0 + 0.25 + 1 + + enable_bloom + 0 + enable_color_filter + 1 + enable_gauss_blur + 1 + enable_motionblur + 1 + enable_night_vision + 0 + enable_posterize + 0 + enable_vignette + 1 + extract_high + 1 + extract_low + 0.949999999999999955591079 + gamma + 2 + gauss_blur_passes + 1 + noise_size + 25 + noise_strength + 0.4000000000000000222044605 + posterize_layers + 10 + saturation + 0.0499999523162841796875 + vignette_chromatic_aberration + 0.1000000014901161193847656 + vignette_darkness + 1 + vignette_desaturation + 1 + vignette_radius + 3.9999997615814208984375 + vignette_strength + 1 + + PyFX CatVision v1 Dark + + bloom_strength + 1.5 + bloom_width + 2.25 + blur_strength + 30 + brightness + 2 + brightness_multiplier + 3 + contrast + 3 + contrast_base + + 1 + 0 + 0.25 + 1 + + enable_bloom + 0 + enable_color_filter + 1 + enable_gauss_blur + 1 + enable_motionblur + 1 + enable_night_vision + 0 + enable_posterize + 0 + enable_vignette + 1 + extract_high + 1 + extract_low + 0.949999999999999955591079 + gamma + 2.5 + gauss_blur_passes + 1 + noise_size + 25 + noise_strength + 0.4000000000000000222044605 + posterize_layers + 10 + saturation + 0.0499999523162841796875 + vignette_chromatic_aberration + 0.1000000014901161193847656 + vignette_darkness + 1 + vignette_desaturation + 1 + vignette_radius + 3.9999997615814208984375 + vignette_strength + 1 + + PyFX GrimDark v1 + + bloom_strength + 1.5 + bloom_width + 2.25 + blur_strength + 15 + brightness + 4 + brightness_multiplier + 1 + contrast + 1.25 + contrast_base + + 0.699999988079071044921875 + 0.7999999523162841796875 + 1 + 1 + + enable_bloom + 0 + enable_color_filter + 1 + enable_gauss_blur + 0 + enable_motionblur + 1 + enable_night_vision + 0 + enable_posterize + 0 + enable_vignette + 1 + extract_high + 1 + extract_low + 0.949999999999999955591079 + gamma + 1.25 + gauss_blur_passes + 2 + noise_size + 52.5 + noise_strength + 0.4000000000000000222044605 + posterize_layers + 10 + saturation + 0.5 + vignette_chromatic_aberration + 0.009500000625848770141601563 + vignette_darkness + 1 + vignette_desaturation + 0 + vignette_radius + 2 + vignette_strength + 1 + + PyFX GrimDark v2 + + bloom_strength + 1.5 + bloom_width + 2.25 + blur_strength + 30 + brightness + 4 + brightness_multiplier + 3 + contrast + 1 + contrast_base + + 1 + 1 + 1 + 1 + + enable_bloom + 0 + enable_color_filter + 1 + enable_gauss_blur + 0 + enable_motionblur + 1 + enable_night_vision + 0 + enable_posterize + 0 + enable_vignette + 1 + extract_high + 1 + extract_low + 0.949999999999999955591079 + gamma + 1 + gauss_blur_passes + 2 + noise_size + 25 + noise_strength + 0.4000000000000000222044605 + posterize_layers + 10 + saturation + 0.599999904632568359375 + vignette_chromatic_aberration + 0.009500000625848770141601563 + vignette_darkness + 1 + vignette_desaturation + 0.4000000059604644775390625 + vignette_radius + 2.9999997615814208984375 + vignette_strength + 1 + + PyFX Last Summer + + bloom_strength + 1.5 + bloom_width + 2.25 + blur_strength + 20 + brightness + 1.19999992847442626953125 + brightness_multiplier + 3 + contrast + 1.19999992847442626953125 + contrast_base + + 0.5 + 1 + 1 + 1 + + enable_bloom + 0 + enable_color_filter + 1 + enable_gauss_blur + 0 + enable_motionblur + 1 + enable_night_vision + 0 + enable_posterize + 0 + enable_vignette + 1 + extract_high + 1 + extract_low + 0.949999999999999955591079 + gamma + 2 + gauss_blur_passes + 2 + noise_size + 25 + noise_strength + 0.4000000000000000222044605 + posterize_layers + 10 + saturation + 1.6699998378753662109375 + vignette_chromatic_aberration + 0.001500000013038516044616699 + vignette_darkness + 0.25 + vignette_desaturation + 0 + vignette_radius + 7.999999523162841796875 + vignette_strength + 1 + + PyFX Last Winter + + bloom_strength + 1.5 + bloom_width + 2.25 + blur_strength + 20 + brightness + 1.19999992847442626953125 + brightness_multiplier + 3 + contrast + 1.19999992847442626953125 + contrast_base + + 1 + 0.75 + 0.5 + 1 + + enable_bloom + 0 + enable_color_filter + 1 + enable_gauss_blur + 0 + enable_motionblur + 1 + enable_night_vision + 0 + enable_posterize + 0 + enable_vignette + 1 + extract_high + 1 + extract_low + 0.949999999999999955591079 + gamma + 2 + gauss_blur_passes + 2 + noise_size + 25 + noise_strength + 0.4000000000000000222044605 + posterize_layers + 10 + saturation + 0.7999999523162841796875 + vignette_chromatic_aberration + 0.001500000013038516044616699 + vignette_darkness + 0.25 + vignette_desaturation + 0 + vignette_radius + 7.999999523162841796875 + vignette_strength + 1 + + PyFX Memory v1 + + bloom_strength + 1.5 + bloom_width + 2.25 + blur_strength + 30 + brightness + 1.5 + brightness_multiplier + 3 + contrast + 1.25 + contrast_base + + 0 + 0.66999995708465576171875 + 1 + 1 + + enable_bloom + 0 + enable_color_filter + 1 + enable_gauss_blur + 0 + enable_motionblur + 1 + enable_night_vision + 0 + enable_posterize + 0 + enable_vignette + 1 + extract_high + 1 + extract_low + 0.949999999999999955591079 + gamma + 1.5 + gauss_blur_passes + 2 + noise_size + 25 + noise_strength + 0.4000000000000000222044605 + posterize_layers + 10 + saturation + 0.5 + vignette_chromatic_aberration + 0.005000000353902578353881836 + vignette_darkness + 1 + vignette_desaturation + 0.4000000059604644775390625 + vignette_radius + 5 + vignette_strength + 1 + + PyFX Memory v1 Cold + + bloom_strength + 1.5 + bloom_width + 2.25 + blur_strength + 30 + brightness + 1.5 + brightness_multiplier + 3 + contrast + 1.25 + contrast_base + + 1 + 0.329999983310699462890625 + 0 + 1 + + enable_bloom + 0 + enable_color_filter + 1 + enable_gauss_blur + 0 + enable_motionblur + 1 + enable_night_vision + 0 + enable_posterize + 0 + enable_vignette + 1 + extract_high + 1 + extract_low + 0.949999999999999955591079 + gamma + 1.5 + gauss_blur_passes + 2 + noise_size + 25 + noise_strength + 0.4000000000000000222044605 + posterize_layers + 10 + saturation + 0.5 + vignette_chromatic_aberration + 0.005000000353902578353881836 + vignette_darkness + 1 + vignette_desaturation + 0.4000000059604644775390625 + vignette_radius + 5 + vignette_strength + 1 + + PyFX Memory v2 + + bloom_strength + 1.5 + bloom_width + 2.25 + blur_strength + 20 + brightness + 1 + brightness_multiplier + 3 + contrast + 1.2400000095367431640625 + contrast_base + + 0 + 0.62000000476837158203125 + 1 + 1 + + enable_bloom + 0 + enable_color_filter + 1 + enable_gauss_blur + 0 + enable_motionblur + 1 + enable_night_vision + 0 + enable_posterize + 0 + enable_vignette + 1 + extract_high + 1 + extract_low + 0.949999999999999955591079 + gamma + 2 + gauss_blur_passes + 2 + noise_size + 25 + noise_strength + 0.4000000000000000222044605 + posterize_layers + 10 + saturation + 1.3299999237060546875 + vignette_chromatic_aberration + 0.003000000026077032089233398 + vignette_darkness + 0.5 + vignette_desaturation + 0.5 + vignette_radius + 7.999999523162841796875 + vignette_strength + 1 + + PyFX Memory v2 Cold + + bloom_strength + 1.5 + bloom_width + 2.25 + blur_strength + 20 + brightness + 1 + brightness_multiplier + 3 + contrast + 1.2400000095367431640625 + contrast_base + + 1 + 0.319999992847442626953125 + 0 + 1 + + enable_bloom + 0 + enable_color_filter + 1 + enable_gauss_blur + 0 + enable_motionblur + 1 + enable_night_vision + 0 + enable_posterize + 0 + enable_vignette + 1 + extract_high + 1 + extract_low + 0.949999999999999955591079 + gamma + 2 + gauss_blur_passes + 2 + noise_size + 25 + noise_strength + 0.4000000000000000222044605 + posterize_layers + 10 + saturation + 1.3299999237060546875 + vignette_chromatic_aberration + 0.003000000026077032089233398 + vignette_darkness + 0.5 + vignette_desaturation + 0.5 + vignette_radius + 7.999999523162841796875 + vignette_strength + 1 + + PyFX Mono v1 + + bloom_strength + 1.5 + bloom_width + 2.25 + blur_strength + 30 + brightness + 1 + brightness_multiplier + 3 + contrast + 4 + contrast_base + + 1 + 1 + 1 + 0 + + enable_bloom + 0 + enable_color_filter + 1 + enable_gauss_blur + 0 + enable_motionblur + 1 + enable_night_vision + 0 + enable_posterize + 1 + enable_vignette + 1 + extract_high + 1 + extract_low + 0.949999999999999955591079 + gamma + 1 + gauss_blur_passes + 1 + noise_size + 25 + noise_strength + 0.4000000000000000222044605 + posterize_layers + 3 + saturation + 0 + vignette_chromatic_aberration + 0 + vignette_darkness + 1 + vignette_desaturation + 1 + vignette_radius + 1 + vignette_strength + 1 + + PyFX Neo v1 + + bloom_strength + 1.5 + bloom_width + 2.25 + blur_strength + 15 + brightness + 1.5 + brightness_multiplier + 1 + contrast + 1.25 + contrast_base + + 1 + 1 + 0.75 + 1 + + enable_bloom + 0 + enable_color_filter + 1 + enable_gauss_blur + 0 + enable_motionblur + 1 + enable_night_vision + 0 + enable_posterize + 0 + enable_vignette + 1 + extract_high + 1 + extract_low + 0.949999999999999955591079 + gamma + 1.25 + gauss_blur_passes + 2 + noise_size + 52.5 + noise_strength + 0.4000000000000000222044605 + posterize_layers + 10 + saturation + 0.849999904632568359375 + vignette_chromatic_aberration + 0.009500000625848770141601563 + vignette_darkness + 1 + vignette_desaturation + 0 + vignette_radius + 2 + vignette_strength + 1 + + PyFX Neo v1 Bright + + bloom_strength + 1.5 + bloom_width + 2.25 + blur_strength + 15 + brightness + 2.5 + brightness_multiplier + 1 + contrast + 1.25 + contrast_base + + 1 + 1 + 0.75 + 1 + + enable_bloom + 0 + enable_color_filter + 1 + enable_gauss_blur + 0 + enable_motionblur + 1 + enable_night_vision + 0 + enable_posterize + 0 + enable_vignette + 1 + extract_high + 1 + extract_low + 0.949999999999999955591079 + gamma + 1.25 + gauss_blur_passes + 2 + noise_size + 52.5 + noise_strength + 0.4000000000000000222044605 + posterize_layers + 10 + saturation + 0.849999904632568359375 + vignette_chromatic_aberration + 0.009500000625848770141601563 + vignette_darkness + 1 + vignette_desaturation + 0 + vignette_radius + 2 + vignette_strength + 1 + + PyFX Retrowave + + bloom_strength + 1.5 + bloom_width + 2.25 + blur_strength + 20 + brightness + 1 + brightness_multiplier + 3 + contrast + 1.2400000095367431640625 + contrast_base + + 0.2999999821186065673828125 + 1 + 0 + 1 + + enable_bloom + 0 + enable_color_filter + 1 + enable_gauss_blur + 0 + enable_motionblur + 1 + enable_night_vision + 0 + enable_posterize + 0 + enable_vignette + 1 + extract_high + 1 + extract_low + 0.949999999999999955591079 + gamma + 1.5 + gauss_blur_passes + 2 + noise_size + 25 + noise_strength + 0.4000000000000000222044605 + posterize_layers + 10 + saturation + 1.5 + vignette_chromatic_aberration + 0.003000000026077032089233398 + vignette_darkness + 0.5 + vignette_desaturation + 0 + vignette_radius + 7.999999523162841796875 + vignette_strength + 1 + + PyFX Twilight v1 Cold + + bloom_strength + 1.5 + bloom_width + 2.25 + blur_strength + 30 + brightness + 1.25 + brightness_multiplier + 3 + contrast + 1.0299999713897705078125 + contrast_base + + 1 + 0.329999983310699462890625 + 0 + 1 + + enable_bloom + 0 + enable_color_filter + 1 + enable_gauss_blur + 0 + enable_motionblur + 1 + enable_night_vision + 0 + enable_posterize + 0 + enable_vignette + 1 + extract_high + 1 + extract_low + 0.949999999999999955591079 + gamma + 1.5 + gauss_blur_passes + 2 + noise_size + 25 + noise_strength + 0.4000000000000000222044605 + posterize_layers + 10 + saturation + 0.5 + vignette_chromatic_aberration + 0.005000000353902578353881836 + vignette_darkness + 1 + vignette_desaturation + 0.4000000059604644775390625 + vignette_radius + 5 + vignette_strength + 1 + + PyFX Twilight v1 Warm + + bloom_strength + 1.5 + bloom_width + 2.25 + blur_strength + 30 + brightness + 1.25 + brightness_multiplier + 3 + contrast + 1.0299999713897705078125 + contrast_base + + 0 + 0.66999995708465576171875 + 1 + 1 + + enable_bloom + 0 + enable_color_filter + 1 + enable_gauss_blur + 0 + enable_motionblur + 1 + enable_night_vision + 0 + enable_posterize + 0 + enable_vignette + 1 + extract_high + 1 + extract_low + 0.949999999999999955591079 + gamma + 1.5 + gauss_blur_passes + 2 + noise_size + 25 + noise_strength + 0.4000000000000000222044605 + posterize_layers + 10 + saturation + 0.5 + vignette_chromatic_aberration + 0.005000000353902578353881836 + vignette_darkness + 1 + vignette_desaturation + 0.4000000059604644775390625 + vignette_radius + 5 + vignette_strength + 1 + + PyFX Underwater + + bloom_strength + 1.5 + bloom_width + 2.25 + blur_strength + 30 + brightness + 1.14999997615814208984375 + brightness_multiplier + 3 + contrast + 0.89999997615814208984375 + contrast_base + + 0 + 0.5 + 1 + 1 + + enable_bloom + 0 + enable_color_filter + 1 + enable_gauss_blur + 1 + enable_motionblur + 1 + enable_night_vision + 0 + enable_posterize + 0 + enable_vignette + 1 + extract_high + 1 + extract_low + 0.949999999999999955591079 + gamma + 0.75 + gauss_blur_passes + 1 + noise_size + 25 + noise_strength + 0.4000000000000000222044605 + posterize_layers + 10 + saturation + 0.75 + vignette_chromatic_aberration + 0.01000000070780515670776367 + vignette_darkness + 0.5 + vignette_desaturation + 0 + vignette_radius + 7.999999523162841796875 + vignette_strength + 1 + + PyFX Underwater Murky + + bloom_strength + 1.5 + bloom_width + 2.25 + blur_strength + 30 + brightness + 0.829999983310699462890625 + brightness_multiplier + 3 + contrast + 0.89999997615814208984375 + contrast_base + + 0.64999997615814208984375 + 1 + 0 + 1 + + enable_bloom + 0 + enable_color_filter + 1 + enable_gauss_blur + 1 + enable_motionblur + 1 + enable_night_vision + 0 + enable_posterize + 0 + enable_vignette + 1 + extract_high + 1 + extract_low + 0.949999999999999955591079 + gamma + 0.7999999523162841796875 + gauss_blur_passes + 2 + noise_size + 25 + noise_strength + 0.4000000000000000222044605 + posterize_layers + 10 + saturation + 0.3999998569488525390625 + vignette_chromatic_aberration + 0.01000000070780515670776367 + vignette_darkness + 0.5 + vignette_desaturation + 0 + vignette_radius + 7.999999523162841796875 + vignette_strength + 1 + + PyFX Vivid v1 + + bloom_strength + 1.5 + bloom_width + 2.25 + blur_strength + 30 + brightness + 1.19999992847442626953125 + brightness_multiplier + 3 + contrast + 1.25 + contrast_base + + 0.7999999523162841796875 + 0.89999997615814208984375 + 1 + 1 + + enable_bloom + 0 + enable_color_filter + 1 + enable_gauss_blur + 0 + enable_motionblur + 1 + enable_night_vision + 0 + enable_posterize + 0 + enable_vignette + 1 + extract_high + 1 + extract_low + 0.949999999999999955591079 + gamma + 2 + gauss_blur_passes + 2 + noise_size + 25 + noise_strength + 0.4000000000000000222044605 + posterize_layers + 10 + saturation + 1.19999980926513671875 + vignette_chromatic_aberration + 0.004500000271946191787719727 + vignette_darkness + 1 + vignette_desaturation + 0 + vignette_radius + 2.9999997615814208984375 + vignette_strength + 1 + + PyFX Vivid v1 Cold + + bloom_strength + 1.5 + bloom_width + 2.25 + blur_strength + 30 + brightness + 1.19999992847442626953125 + brightness_multiplier + 3 + contrast + 1.25 + contrast_base + + 1 + 0.89999997615814208984375 + 0.7999999523162841796875 + 1 + + enable_bloom + 0 + enable_color_filter + 1 + enable_gauss_blur + 0 + enable_motionblur + 1 + enable_night_vision + 0 + enable_posterize + 0 + enable_vignette + 1 + extract_high + 1 + extract_low + 0.949999999999999955591079 + gamma + 2 + gauss_blur_passes + 2 + noise_size + 25 + noise_strength + 0.4000000000000000222044605 + posterize_layers + 10 + saturation + 1.19999980926513671875 + vignette_chromatic_aberration + 0.004500000271946191787719727 + vignette_darkness + 1 + vignette_desaturation + 0 + vignette_radius + 2.9999997615814208984375 + vignette_strength + 1 + + PyFX Vivid v2 + + bloom_strength + 1.5 + bloom_width + 2.25 + blur_strength + 20 + brightness + 1 + brightness_multiplier + 3 + contrast + 1.5 + contrast_base + + 1 + 1 + 1 + 1 + + enable_bloom + 0 + enable_color_filter + 1 + enable_gauss_blur + 0 + enable_motionblur + 1 + enable_night_vision + 0 + enable_posterize + 0 + enable_vignette + 1 + extract_high + 1 + extract_low + 0.949999999999999955591079 + gamma + 3 + gauss_blur_passes + 2 + noise_size + 25 + noise_strength + 0.4000000000000000222044605 + posterize_layers + 10 + saturation + 1.5 + vignette_chromatic_aberration + 0.002000000094994902610778809 + vignette_darkness + 0.2999999821186065673828125 + vignette_desaturation + 0 + vignette_radius + 7.999999523162841796875 + vignette_strength + 1 + + PyFX Vivid v2 Bright + + bloom_strength + 1.5 + bloom_width + 2.25 + blur_strength + 15 + brightness + 1.25 + brightness_multiplier + 3 + contrast + 1.5 + contrast_base + + 1 + 1 + 1 + 1 + + enable_bloom + 0 + enable_color_filter + 1 + enable_gauss_blur + 0 + enable_motionblur + 1 + enable_night_vision + 0 + enable_posterize + 0 + enable_vignette + 1 + extract_high + 1 + extract_low + 0.949999999999999955591079 + gamma + 3 + gauss_blur_passes + 2 + noise_size + 25 + noise_strength + 0.4000000000000000222044605 + posterize_layers + 10 + saturation + 1.5 + vignette_chromatic_aberration + 0.01000000000000000020816682 + vignette_darkness + 1 + vignette_desaturation + 1 + vignette_radius + 1 + vignette_strength + 1 + + PyFX Vivid v2 Dark + + bloom_strength + 1.5 + bloom_width + 2.25 + blur_strength + 15 + brightness + 1 + brightness_multiplier + 3 + contrast + 1.5 + contrast_base + + 1 + 1 + 1 + 1 + + enable_bloom + 0 + enable_color_filter + 1 + enable_gauss_blur + 0 + enable_motionblur + 1 + enable_night_vision + 0 + enable_posterize + 0 + enable_vignette + 1 + extract_high + 1 + extract_low + 0.949999999999999955591079 + gamma + 3 + gauss_blur_passes + 2 + noise_size + 25 + noise_strength + 0.4000000000000000222044605 + posterize_layers + 10 + saturation + 1.5 + vignette_chromatic_aberration + 0.01000000000000000020816682 + vignette_darkness + 1 + vignette_desaturation + 1 + vignette_radius + 1 + vignette_strength + 1 + + PyFX v1 + + bloom_strength + 1.5 + bloom_width + 2.25 + blur_strength + 30 + brightness + 1.19999992847442626953125 + brightness_multiplier + 3 + contrast + 1.25 + contrast_base + + 0.7999999523162841796875 + 0.89999997615814208984375 + 1 + 1 + + enable_bloom + 0 + enable_color_filter + 1 + enable_gauss_blur + 0 + enable_motionblur + 1 + enable_night_vision + 0 + enable_posterize + 0 + enable_vignette + 1 + extract_high + 1 + extract_low + 0.949999999999999955591079 + gamma + 2 + gauss_blur_passes + 2 + noise_size + 25 + noise_strength + 0.4000000000000000222044605 + posterize_layers + 10 + saturation + 0.7999999523162841796875 + vignette_chromatic_aberration + 0.004500000271946191787719727 + vignette_darkness + 1 + vignette_desaturation + 0 + vignette_radius + 1.5 + vignette_strength + 1 + + PyFX v2 + + bloom_strength + 1.5 + bloom_width + 2.25 + blur_strength + 30 + brightness + 1 + brightness_multiplier + 3 + contrast + 2 + contrast_base + + 0.949999988079071044921875 + 0.969999969005584716796875 + 1 + 1 + + enable_bloom + 1 + enable_color_filter + 1 + enable_gauss_blur + 0 + enable_motionblur + 1 + enable_night_vision + 0 + enable_posterize + 0 + enable_vignette + 1 + extract_high + 1 + extract_low + 0.949999999999999955591079 + gamma + 5 + gauss_blur_passes + 2 + noise_size + 25 + noise_strength + 0.4000000000000000222044605 + posterize_layers + 10 + saturation + 1 + vignette_chromatic_aberration + 0.004500000271946191787719727 + vignette_darkness + 1 + vignette_desaturation + 0 + vignette_radius + 1.5 + vignette_strength + 1 + + PyFX v3 + + bloom_strength + 1.5 + bloom_width + 2.25 + blur_strength + 30 + brightness + 1 + brightness_multiplier + 3 + contrast + 1.75 + contrast_base + + 0.949999988079071044921875 + 0.969999969005584716796875 + 1 + 1 + + enable_bloom + 1 + enable_color_filter + 1 + enable_gauss_blur + 0 + enable_motionblur + 1 + enable_night_vision + 0 + enable_posterize + 0 + enable_vignette + 1 + extract_high + 1 + extract_low + 0.949999999999999955591079 + gamma + 4 + gauss_blur_passes + 2 + noise_size + 25 + noise_strength + 0.4000000000000000222044605 + posterize_layers + 10 + saturation + 1.099999904632568359375 + vignette_chromatic_aberration + 0.004500000271946191787719727 + vignette_darkness + 0.66999995708465576171875 + vignette_desaturation + 0 + vignette_radius + 2.9999997615814208984375 + vignette_strength + 1 + + diff --git a/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Cloudy%20Dusk.xml b/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Cloudy%20Dusk.xml new file mode 100644 index 000000000..8fe71abd1 --- /dev/null +++ b/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Cloudy%20Dusk.xml @@ -0,0 +1,106 @@ + + + ambient + + 0 + 0.05999999865889549255371094 + 0.1499999910593032836914063 + 0.04999999701976776123046875 + + blue_density + + 1.99999988079071044921875 + 1.99999988079071044921875 + 1.99999988079071044921875 + 1 + + blue_horizon + + 0.680000007152557373046875 + 0.680000007152557373046875 + 0.680000007152557373046875 + 0.3400000035762786865234375 + + cloud_color + + 0.2999999821186065673828125 + 0.2999999821186065673828125 + 0.2999999821186065673828125 + 0.2999999821186065673828125 + + cloud_pos_density1 + + 1 + 1 + 0.0999999940395355224609375 + 1 + + cloud_pos_density2 + + 1.6884100437164306640625 + 1 + 0.0999999940395355224609375 + 1 + + cloud_scale + 0.2000000029802322387695313 + cloud_scroll_rate + + 10.1499996185302734375 + 10 + + cloud_shadow + 0.5 + density_multiplier + 5.999999848427250981330872e-05 + distance_multiplier + 3 + east_angle + 0 + enable_cloud_scroll + + 1 + 1 + + gamma + + 1.75 + 0 + 0 + 1 + + glow + + 10 + 0.001000000047497451305389404 + -0.449999988079071044921875 + 1 + + haze_density + 4 + haze_horizon + 0 + lightnorm + + 0 + 0 + -1 + 0 + + max_y + 500 + preset_num + 22 + star_brightness + 0 + sun_angle + 3.1415927410125732421875 + sunlight_color + + 0.2999999821186065673828125 + 0.38999998569488525390625 + 0.4500000178813934326171875 + 0.1499999910593032836914063 + + + diff --git a/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Night%20Cloudy.xml b/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Night%20Cloudy.xml new file mode 100644 index 000000000..92c786b82 --- /dev/null +++ b/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Night%20Cloudy.xml @@ -0,0 +1,106 @@ + + + ambient + + 0.04499999806284904479980469 + 0.06749998778104782104492188 + 0.08999999612569808959960938 + 0.02999999932944774627685547 + + blue_density + + 2 + 2 + 2 + 1 + + blue_horizon + + 0.5 + 0.5 + 0.5 + 0.25 + + cloud_color + + 0.1400000005960464477539063 + 0.1400000005960464477539063 + 0.1400000005960464477539063 + 0.1400000005960464477539063 + + cloud_pos_density1 + + 1 + 1 + 0.25 + 1 + + cloud_pos_density2 + + 1.6884100437164306640625 + 1 + 0 + 1 + + cloud_scale + 0.2000000029802322387695313 + cloud_scroll_rate + + 10.3999996185302734375 + 10 + + cloud_shadow + 0.599999964237213134765625 + density_multiplier + 4.999999873689375817775726e-05 + distance_multiplier + 7 + east_angle + 0 + enable_cloud_scroll + + 1 + 1 + + gamma + + 0.75 + 0 + 0 + 1 + + glow + + 10 + 0.001000000047497451305389404 + -0.449999988079071044921875 + 1 + + haze_density + 4 + haze_horizon + 0 + lightnorm + + 0 + 0 + -1 + 0 + + max_y + 1 + preset_num + 22 + star_brightness + 0 + sun_angle + 3.1415927410125732421875 + sunlight_color + + 0 + 0 + 0 + 0 + + + diff --git a/indra/newview/ascentprefschat.cpp b/indra/newview/ascentprefschat.cpp index 150c9a3a4..084cc448f 100644 --- a/indra/newview/ascentprefschat.cpp +++ b/indra/newview/ascentprefschat.cpp @@ -112,57 +112,75 @@ void LLPrefsAscentChat::onSpellBaseComboBoxCommit(const LLSD& value) glggHunSpell->newDictSelection(value.asString()); } +void setTimeDateFormats(const S8& tempTimeFormat, const S8& tempDateFormat) +{ + std::string short_date, long_date, short_time, long_time, timestamp; + + if (tempDateFormat != -1) + { + if (tempDateFormat < 3) + { + short_date = !tempDateFormat ? "%F" : + tempDateFormat == 1 ? "%Y/%m/%d" : + "%d/%m/%Y"; + long_date = "%A, %d %B %Y"; + timestamp = "%a %d %b %Y"; + } + else + { + short_date = "%m/%d/%Y"; + long_date = "%A, %B %d %Y"; + timestamp = "%a %b %d %Y"; + } + } + + if (tempTimeFormat != -1) + { + if (tempTimeFormat == 0) + { + short_time = "%R"; + long_time = "%T"; + if (!timestamp.empty()) timestamp += " %T"; + } + else + { + short_time = "%I:%M %p"; + long_time = "%I:%M:%S %p"; + if (!timestamp.empty()) timestamp += " %I:%M %p"; + } + } + else if (!timestamp.empty()) + { + timestamp += ' ' + gSavedSettings.getString("ShortTimeFormat"); + } + + if (!short_date.empty()) + { + gSavedSettings.setString("ShortDateFormat", short_date); + gSavedSettings.setString("LongDateFormat", long_date); + } + if (!short_time.empty()) + { + gSavedSettings.setString("ShortTimeFormat", short_time); + gSavedSettings.setString("LongTimeFormat", long_time); + } + if (!timestamp.empty()) + gSavedSettings.setString("TimestampFormat", timestamp); +} + void LLPrefsAscentChat::onCommitTimeDate(LLUICtrl* ctrl) { LLComboBox* combo = static_cast(ctrl); - if (ctrl->getName() == "time_format_combobox") - { + if (ctrl->getName() == "time_format_combobox") + { tempTimeFormat = combo->getCurrentIndex(); - } - else if (ctrl->getName() == "date_format_combobox") - { + } + else if (ctrl->getName() == "date_format_combobox") + { tempDateFormat = combo->getCurrentIndex(); - } + } - std::string short_date, long_date, short_time, long_time, timestamp; - - if (tempTimeFormat == 0) - { - short_time = "%R"; - long_time = "%T"; - timestamp = " %T"; - } - else - { - short_time = "%I:%M %p"; - long_time = "%I:%M:%S %p"; - timestamp = " %I:%M %p"; - } - - if (tempDateFormat == 0) - { - short_date = "%F"; - long_date = "%A %d %B %Y"; - timestamp = "%a %d %b %Y" + timestamp; - } - else if (tempDateFormat == 1) - { - short_date = "%d/%m/%Y"; - long_date = "%A %d %B %Y"; - timestamp = "%a %d %b %Y" + timestamp; - } - else - { - short_date = "%D"; - long_date = "%A, %B %d %Y"; - timestamp = "%a %b %d %Y" + timestamp; - } - - gSavedSettings.setString("ShortDateFormat", short_date); - gSavedSettings.setString("LongDateFormat", long_date); - gSavedSettings.setString("ShortTimeFormat", short_time); - gSavedSettings.setString("LongTimeFormat", long_time); - gSavedSettings.setString("TimestampFormat", timestamp); + setTimeDateFormats(tempTimeFormat, tempDateFormat); } void LLPrefsAscentChat::onCommitKeywords(LLUICtrl* ctrl) @@ -208,28 +226,16 @@ void LLPrefsAscentChat::refreshValues() mSecondsInLog = gSavedSettings.getBOOL("SecondsInLog"); std::string format = gSavedSettings.getString("ShortTimeFormat"); - if (format.find("%p") == std::string::npos) - { - mTimeFormat = 0; - } - else - { - mTimeFormat = 1; - } + mTimeFormat = format == "%R" ? 0 + : format == "%I:%M %p" ? 1 + : -1; format = gSavedSettings.getString("ShortDateFormat"); - if (format.find("%D") != std::string::npos || format.find("%m/%d/%") != std::string::npos) - { - mDateFormat = 2; - } - else if (format.find("%d/%m/%") != std::string::npos) - { - mDateFormat = 1; - } - else - { - mDateFormat = 0; - } + mDateFormat = format == "%F" ? 0 : + format == "%Y/%m/%d" ? 1 : + format == "%d/%m/%Y" ? 2 : + format == "%m/%d/%Y" ? 3 : + -1; tempTimeFormat = mTimeFormat; tempDateFormat = mDateFormat; @@ -316,83 +322,78 @@ void LLPrefsAscentChat::refreshValues() // Update controls based on current settings void LLPrefsAscentChat::refresh() { - //Chat -------------------------------------------------------------------------------- - // time format combobox - LLComboBox* combo = getChild("time_format_combobox"); - if (combo) - { - combo->setCurrentByIndex(mTimeFormat); - } + //Chat -------------------------------------------------------------------------------- + // time format combobox + if (mTimeFormat != -1) + { + if (auto combo = getChild("time_format_combobox")) + { + combo->setCurrentByIndex(mTimeFormat); + } + } - // date format combobox - combo = getChild("date_format_combobox"); - if (combo) - { - combo->setCurrentByIndex(mDateFormat); - } + // date format combobox + if (mDateFormat != -1) + { + if (auto combo = getChild("date_format_combobox")) + { + combo->setCurrentByIndex(mDateFormat); + } + } //Chat UI ----------------------------------------------------------------------------- - if (combo = getChild("chat_tabs_namesystem_combobox")) + if (auto combo = getChild("chat_tabs_namesystem_combobox")) combo->setCurrentByIndex(mChatTabNames); - if (combo = getChild("friends_namesystem_combobox")) + if (auto combo = getChild("friends_namesystem_combobox")) combo->setCurrentByIndex(mFriendNames); - if (combo = getChild("group_members_namesystem_combobox")) + if (auto combo = getChild("group_members_namesystem_combobox")) combo->setCurrentByIndex(mGroupMembersNames); - if (combo = getChild("land_management_namesystem_combobox")) + if (auto combo = getChild("land_management_namesystem_combobox")) combo->setCurrentByIndex(mLandManagementNames); - if (combo = getChild("radar_namesystem_combobox")) + if (auto combo = getChild("radar_namesystem_combobox")) combo->setCurrentByIndex(mRadarNames); - if (combo = getChild("speaker_namesystem_combobox")) + if (auto combo = getChild("speaker_namesystem_combobox")) combo->setCurrentByIndex(mSpeakerNames); //Text Options ------------------------------------------------------------------------ - combo = getChild("SpellBase"); - - if (combo != NULL) + if (auto combo = getChild("SpellBase")) { combo->removeall(); - std::vector names = glggHunSpell->getDicts(); - for (int i = 0; i < (int)names.size(); i++) + for (const auto& name : glggHunSpell->getDicts()) { - combo->add(names[i]); + combo->add(name); } combo->setSimple(gSavedSettings.getString("SpellBase")); } - combo = getChild("EmSpell_Avail"); - - if (combo != NULL) + if (auto combo = getChild("EmSpell_Avail")) { combo->removeall(); - combo->add(""); - std::vector names = glggHunSpell->getAvailDicts(); + combo->add(LLStringUtil::null); - for (int i = 0; i < (int)names.size(); i++) + for (const auto& name : glggHunSpell->getAvailDicts()) { - combo->add(names[i]); + combo->add(name); } - combo->setSimple(std::string("")); + combo->setSimple(LLStringUtil::null); } - combo = getChild("EmSpell_Installed"); - - if (combo != NULL) + if (auto combo = getChild("EmSpell_Installed")) { combo->removeall(); - combo->add(""); - std::vector names = glggHunSpell->getInstalledDicts(); + combo->add(LLStringUtil::null); - for (int i = 0; i < (int)names.size(); i++) + for (const auto& name : glggHunSpell->getInstalledDicts()) { - combo->add(names[i]); + combo->add(name); } - combo->setSimple(std::string("")); + combo->setSimple(LLStringUtil::null); } childSetEnabled("KeywordsList", mKeywordsOn); @@ -434,45 +435,7 @@ void LLPrefsAscentChat::cancel() gSavedSettings.setBOOL("SecondsInChatAndIMs", mSecondsInChatAndIMs); gSavedSettings.setBOOL("SecondsInLog", mSecondsInLog); - std::string short_date, long_date, short_time, long_time, timestamp; - - if (mTimeFormat == 0) - { - short_time = "%H:%M"; - long_time = "%H:%M:%S"; - timestamp = " %H:%M:%S"; - } - else - { - short_time = "%I:%M %p"; - long_time = "%I:%M:%S %p"; - timestamp = " %I:%M %p"; - } - - if (mDateFormat == 0) - { - short_date = "%Y-%m-%d"; - long_date = "%A %d %B %Y"; - timestamp = "%a %d %b %Y" + timestamp; - } - else if (mDateFormat == 1) - { - short_date = "%d/%m/%Y"; - long_date = "%A %d %B %Y"; - timestamp = "%a %d %b %Y" + timestamp; - } - else - { - short_date = "%m/%d/%Y"; - long_date = "%A, %B %d %Y"; - timestamp = "%a %b %d %Y" + timestamp; - } - - gSavedSettings.setString("ShortDateFormat", short_date); - gSavedSettings.setString("LongDateFormat", long_date); - gSavedSettings.setString("ShortTimeFormat", short_time); - gSavedSettings.setString("LongTimeFormat", long_time); - gSavedSettings.setString("TimestampFormat", timestamp); + setTimeDateFormats(mTimeFormat, mDateFormat); //Chat UI ----------------------------------------------------------------------------- gSavedSettings.setBOOL("WoLfVerticalIMTabs", mWoLfVerticalIMTabs); diff --git a/indra/newview/ascentprefschat.h b/indra/newview/ascentprefschat.h index 7f0e4a87a..2521b2039 100644 --- a/indra/newview/ascentprefschat.h +++ b/indra/newview/ascentprefschat.h @@ -67,10 +67,10 @@ private: bool mEnableMUPose; bool mEnableOOCAutoClose; U32 mLinksForChattingObjects; - U32 mTimeFormat; - U32 mDateFormat; - U32 tempTimeFormat; - U32 tempDateFormat; + S8 mTimeFormat; + S8 mDateFormat; + S8 tempTimeFormat; + S8 tempDateFormat; bool mSecondsInChatAndIMs; bool mSecondsInLog; diff --git a/indra/newview/floatervoicelicense.cpp b/indra/newview/floatervoicelicense.cpp deleted file mode 100644 index 4250e6211..000000000 --- a/indra/newview/floatervoicelicense.cpp +++ /dev/null @@ -1,244 +0,0 @@ -/** -* @file floatervoicelicense.cpp -* @brief prompts user to agree to the Vivox license in order to enable voice -* -* $LicenseInfo:firstyear=2009&license=viewergpl$ -* -* Copyright (c) 2010, McCabe Maxsted -* -* Imprudence Viewer Source Code -* The source code in this file ("Source Code") is provided to you -* under the terms of the GNU General Public License, version 2.0 -* ("GPL"). Terms of the GPL can be found in doc/GPL-license.txt in -* this distribution, or online at -* http://secondlifegrid.net/programs/open_source/licensing/gplv2 -* -* There are special exceptions to the terms and conditions of the GPL as -* it is applied to this Source Code. View the full text of the exception -* in the file doc/FLOSS-exception.txt in this software distribution, or -* online at http://secondlifegrid.net/programs/open_source/licensing/flossexception -* -* By copying, modifying or distributing this software, you acknowledge -* that you have read and understood your obligations described above, -* and agree to abide by those obligations. -* -* ALL SOURCE CODE IS PROVIDED "AS IS." THE AUTHOR MAKES NO -* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, -* COMPLETENESS OR PERFORMANCE. -* $/LicenseInfo$ -*/ - -#include "llviewerprecompiledheaders.h" - -#include "floatervoicelicense.h" - -// viewer includes -#include "llagent.h" -#include "llappviewer.h" -#include "llstartup.h" -#include "llviewercontrol.h" -#include "llviewerstats.h" -#include "llviewertexteditor.h" -#include "llviewerwindow.h" - -// linden library includes -#include "llbutton.h" -#include "llhttpclient.h" -#include "llhttpstatuscodes.h" // for HTTP_FOUND -#include "llradiogroup.h" -#include "lltextbox.h" -#include "llui.h" -#include "lluictrlfactory.h" -#include "llvfile.h" -#include "message.h" - -class AIHTTPTimeoutPolicy; -extern AIHTTPTimeoutPolicy iamHereVoice_timeout; - -FloaterVoiceLicense::FloaterVoiceLicense(const LLSD& key) -: LLModalDialog( std::string(" "), 100, 100 ), - mLoadCompleteCount( 0 ) -{ - LLUICtrlFactory::getInstance()->buildFloater(this, "floater_voice_license.xml"); -} - -// helper class that trys to download a URL from a web site and calls a method -// on parent class indicating if the web server is working or not -class LLIamHereVoice : public LLHTTPClient::ResponderWithResult -{ - private: - LLIamHereVoice( FloaterVoiceLicense* parent ) : - mParent( parent ) - {} - - FloaterVoiceLicense* mParent; - - public: - static boost::intrusive_ptr< LLIamHereVoice > build( FloaterVoiceLicense* parent ) - { - return boost::intrusive_ptr< LLIamHereVoice >( new LLIamHereVoice( parent ) ); - }; - - virtual void setParent( FloaterVoiceLicense* parentIn ) - { - mParent = parentIn; - }; - - /*virtual*/ void httpSuccess(void) - { - if ( mParent ) - mParent->setSiteIsAlive( true ); - }; - - /*virtual*/ void httpFailure(void) - { - if ( mParent ) - { - // *HACK: For purposes of this alive check, 302 Found - // (aka Moved Temporarily) is considered alive. The web site - // redirects this link to a "cache busting" temporary URL. JC - bool alive = (mStatus == HTTP_FOUND); - mParent->setSiteIsAlive( alive ); - } - }; - - /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return iamHereVoice_timeout; } - /*virtual*/ bool pass_redirect_status(void) const { return true; } - /*virtual*/ char const* getName(void) const { return "LLIamHereVoice"; } -}; - -// this is global and not a class member to keep crud out of the header file -namespace { - boost::intrusive_ptr< LLIamHereVoice > gResponsePtr = 0; -}; - -BOOL FloaterVoiceLicense::postBuild() -{ - childSetAction("Continue", onContinue, this); - childSetAction("Cancel", onCancel, this); - childSetCommitCallback("agree_chk", updateAgree, this); - - // disable Agree to License radio button until the page has fully loaded - LLCheckBoxCtrl* license_agreement = getChild("agree_chk"); - license_agreement->setEnabled( false ); - - // hide the SL text widget if we're displaying license with using a browser widget. - LLTextEditor *editor = getChild("license_text"); - editor->setVisible( FALSE ); - - LLMediaCtrl* web_browser = getChild("license_html"); - if ( web_browser ) - { - // start to observe it so we see navigate complete events - web_browser->addObserver( this ); - std::string url = getString( "real_url" ); - if(url.substr(0,4) == "http") { - gResponsePtr = LLIamHereVoice::build( this ); - LLHTTPClient::get( url, gResponsePtr ); - } else { - setSiteIsAlive(false); - } - } - - return TRUE; -} - -void FloaterVoiceLicense::setSiteIsAlive( bool alive ) -{ - LLMediaCtrl* web_browser = getChild("license_html"); - // if the contents of the site was retrieved - if ( alive ) - { - if ( web_browser ) - { - // navigate to the "real" page - std::string real_url = getString( "real_url" ); - web_browser->navigateTo(real_url); - } - } - else - { - web_browser->navigateToLocalPage("license", getString("fallback_html")); - // normally this is set when navigation to license page completes (so you can't accept before it loads) - // but if the page is unavailable, we need to do this now - LLCheckBoxCtrl* license_agreement = getChild("agree_chk"); - license_agreement->setEnabled( true ); - } -} - -FloaterVoiceLicense::~FloaterVoiceLicense() -{ - - // tell the responder we're not here anymore - if ( gResponsePtr ) - { - gResponsePtr->setParent( 0 ); - } -} - -// virtual -void FloaterVoiceLicense::draw() -{ - // draw children - LLModalDialog::draw(); -} - -// static -void FloaterVoiceLicense::updateAgree(LLUICtrl*, void* userdata ) -{ - FloaterVoiceLicense* self = (FloaterVoiceLicense*) userdata; - bool agree = self->childGetValue("agree_chk").asBoolean(); - self->childSetEnabled("Continue", agree); -} - -// static -void FloaterVoiceLicense::onContinue( void* userdata ) -{ - FloaterVoiceLicense* self = (FloaterVoiceLicense*) userdata; - LL_INFOS() << "User agreed to the Vivox personal license" << LL_ENDL; - - // enabling voice by default here seems like the best behavior - gSavedSettings.setBOOL("EnableVoiceChat", TRUE); - gSavedSettings.setBOOL("VivoxLicenseAccepted", TRUE); - - // save these settings in case something bad happens later - gSavedSettings.saveToFile(gSavedSettings.getString("ClientSettingsFile"), TRUE); - - if (LLStartUp::getStartupState() == STATE_LOGIN_VOICE_LICENSE) - { - LLStartUp::setStartupState( STATE_LOGIN_AUTH_INIT ); // Go back and finish authentication - } - self->close(); // destroys this object -} - -// static -void FloaterVoiceLicense::onCancel( void* userdata ) -{ - FloaterVoiceLicense* self = (FloaterVoiceLicense*) userdata; - LL_INFOS() << "User disagreed with the vivox personal license" << LL_ENDL; - gSavedSettings.setBOOL("EnableVoiceChat", FALSE); - gSavedSettings.setBOOL("VivoxLicenseAccepted", FALSE); - - if (LLStartUp::getStartupState() == STATE_LOGIN_VOICE_LICENSE) - { - LLStartUp::setStartupState( STATE_LOGIN_AUTH_INIT ); // Go back and finish authentication - } - self->mLoadCompleteCount = 0; // reset counter for next time we come here - self->close(); // destroys this object -} - -//virtual -void FloaterVoiceLicense::handleMediaEvent(LLPluginClassMedia* /*self*/, EMediaEvent event) -{ - if(event == MEDIA_EVENT_NAVIGATE_COMPLETE) - { - // skip past the loading screen navigate complete - if ( ++mLoadCompleteCount == 2 ) - { - LL_INFOS() << "NAVIGATE COMPLETE" << LL_ENDL; - // enable Agree to License radio button now that page has loaded - LLCheckBoxCtrl * license_agreement = getChild("agree_chk"); - license_agreement->setEnabled( true ); - } - } -} diff --git a/indra/newview/floatervoicelicense.h b/indra/newview/floatervoicelicense.h deleted file mode 100644 index 10aaa1979..000000000 --- a/indra/newview/floatervoicelicense.h +++ /dev/null @@ -1,72 +0,0 @@ -/** -* @file floatervoicelicense.h -* @brief prompts user to agree to the Vivox license in order to enable voice -* -* $LicenseInfo:firstyear=2009&license=viewergpl$ -* -* Copyright (c) 2010, McCabe Maxsted -* -* Imprudence Viewer Source Code -* The source code in this file ("Source Code") is provided to you -* under the terms of the GNU General Public License, version 2.0 -* ("GPL"). Terms of the GPL can be found in doc/GPL-license.txt in -* this distribution, or online at -* http://secondlifegrid.net/programs/open_source/licensing/gplv2 -* -* There are special exceptions to the terms and conditions of the GPL as -* it is applied to this Source Code. View the full text of the exception -* in the file doc/FLOSS-exception.txt in this software distribution, or -* online at http://secondlifegrid.net/programs/open_source/licensing/flossexception -* -* By copying, modifying or distributing this software, you acknowledge -* that you have read and understood your obligations described above, -* and agree to abide by those obligations. -* -* ALL SOURCE CODE IS PROVIDED "AS IS." THE AUTHOR MAKES NO -* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, -* COMPLETENESS OR PERFORMANCE. -* $/LicenseInfo$ -*/ - -#ifndef FLOATERVOICELICENSE_H -#define FLOATERVOICELICENSE_H - -#include "llfloater.h" - -#include "llmodaldialog.h" -#include "llassetstorage.h" -#include "llmediactrl.h" - -class LLButton; -class LLRadioGroup; -class LLVFS; -class LLTextEditor; -class LLUUID; - -class FloaterVoiceLicense : - public LLModalDialog, - public LLViewerMediaObserver, - public LLFloaterSingleton -{ -public: - FloaterVoiceLicense(const LLSD& key); - virtual ~FloaterVoiceLicense(); - - BOOL postBuild(); - - virtual void draw(); - - static void updateAgree( LLUICtrl *, void* userdata ); - static void onContinue( void* userdata ); - static void onCancel( void* userdata ); - - void setSiteIsAlive( bool alive ); - - // inherited from LLViewerMediaObserver - /*virtual*/ void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event); - -private: - int mLoadCompleteCount; -}; - -#endif // FLOATERVOICELICENSE_H diff --git a/indra/newview/gpu_table.txt b/indra/newview/gpu_table.txt index c65e09ef2..618c8970e 100644 --- a/indra/newview/gpu_table.txt +++ b/indra/newview/gpu_table.txt @@ -217,7 +217,6 @@ ATI Radeon RX700 .*ATI.*RX70.* 1 1 ATI Radeon RX800 .*ATI.*Radeon *RX80.* 2 1 ATI RS880M .*ATI.*RS880M 1 1 ATI Radeon RX9550 .*ATI.*RX9550.* 1 1 -ATI Radeon VE .*ATI.*Radeon.*VE.* 0 0 ATI Radeon X1000 .*ATI.*Radeon *X10.* 0 1 ATI Radeon X1200 .*ATI.*Radeon *X12.* 0 1 ATI Radeon X1300 .*ATI.*Radeon *X13.* 1 1 @@ -276,8 +275,9 @@ AMD RV730 (HD 4600) .*RV730.* 3 1 AMD RV740 (HD 4700) .*RV740.* 3 1 AMD RV770 (HD 4800) .*RV770.* 3 1 AMD RV790 (HD 4800) .*RV790.* 3 1 -AMD Vega .*AMD.*Vega.* 3 1 +AMD Vega .*(AMD|ATI).*Vega.* 3 1 AMD Radeon VII .*AMD.*Radeon ?VII.* 3 1 +AMD Radeon RX Series .*ATI.*(Radeon|ASUS).* RX.* 3 1 ATI 760G/Radeon 3000 .*ATI.*AMD 760G.* 1 1 ATI 780L/Radeon 3000 .*ATI.*AMD 780L.* 1 1 ATI Radeon DDR .*ATI.*Radeon ?DDR.* 0 1 @@ -288,6 +288,7 @@ ATI FirePro 5000 .*ATI.*FirePro V5.* 3 1 ATI FirePro 7000 .*ATI.*FirePro V7.* 3 1 ATI FirePro M .*ATI.*FirePro M.* 3 1 ATI Technologies .*ATI *Technologies.* 0 1 +ATI Radeon VE .*ATI.*Radeon.*VE.* 0 0 // This entry is last to work around the "R300" driver problem. ATI R300 (9700) .*R300.* 1 1 ATI Radeon .*ATI.*(Diamond|Radeon).* 0 1 @@ -438,6 +439,8 @@ NVIDIA GTX 780 .*NVIDIA .*GTX *78.* 3 1 NVIDIA GTX 970 .*NVIDIA .*GTX *97.* 3 1 NVIDIA GTX 980 .*NVIDIA .*GTX *98.* 3 1 NVIDIA GTX TITAN .*NVIDIA .*GTX *TITAN.* 3 1 +NVIDIA GeForce/Quadro RTX .*(GeForce|Quadro) .*RTX.* 3 1 +NVIDIA RTX TITAN .*NVIDIA .*RTX.*TITAN.* 3 1 NVIDIA GT 7xxM .*NVIDIA .*GT *7.* 3 1 NVIDIA C51 .*NVIDIA .*C51.* 0 1 NVIDIA G72 .*NVIDIA .*G72.* 1 1 diff --git a/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi index b915fba4c..b2d52808a 100644 --- a/indra/newview/installers/windows/installer_template.nsi +++ b/indra/newview/installers/windows/installer_template.nsi @@ -409,12 +409,6 @@ Section "Viewer" ;This placeholder is replaced by the complete list of all the files in the installer, by viewer_manifest.py %%INSTALL_FILES%% -!ifdef WIN64_BIN_BUILD - ExecWait '"$INSTDIR\redist\vc_redist.x64.exe" /passive /norestart' -!else - ExecWait '"$INSTDIR\redist\vc_redist.x86.exe" /passive /norestart' -!endif - ;Pass the installer's language to the client to use as a default StrCpy $SHORTCUT_LANG_PARAM "--set InstallLanguage $(LanguageCode)" diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h index c31e758e1..17042fd45 100644 --- a/indra/newview/llagent.h +++ b/indra/newview/llagent.h @@ -621,7 +621,7 @@ private: BOOL mAutoPilotUseRotation; LLVector3 mAutoPilotTargetFacing; F32 mAutoPilotTargetDist; - S32 mAutoPilotNoProgressFrameCount; + U64 mAutoPilotNoProgressFrameCount; F32 mAutoPilotRotationThreshold; std::string mAutoPilotBehaviorName; void (*mAutoPilotFinishedCallback)(BOOL, void *); diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 54d9c56b3..bbeb286a0 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -241,7 +241,6 @@ F32 gSimLastTime; // Used in LLAppViewer::init and send_stats() F32 gSimFrames; BOOL gShowObjectUpdates = FALSE; -BOOL gUseQuickTime = TRUE; BOOL gAcceptTOS = FALSE; BOOL gAcceptCriticalMessage = FALSE; diff --git a/indra/newview/llfirstuse.cpp b/indra/newview/llfirstuse.cpp index b8e8b37dc..718d82b50 100644 --- a/indra/newview/llfirstuse.cpp +++ b/indra/newview/llfirstuse.cpp @@ -45,8 +45,8 @@ #include "llviewercontrol.h" #include "llui.h" #include "llappviewer.h" +#include "llfloatertos.h" #include "lltracker.h" -#include "floatervoicelicense.h" #include "llstartup.h" #include "hippogridmanager.h" @@ -303,8 +303,9 @@ void LLFirstUse::voiceLicenseAgreement() { gSavedSettings.setWarning("FirstVoiceLicense", FALSE); - FloaterVoiceLicense::getInstance()->open(); - FloaterVoiceLicense::getInstance()->center(); + auto inst = LLFloaterTOS::show(LLFloaterTOS::TOS_VOICE); + inst->open(); + inst->center(); } else // currently in STATE_LOGIN_VOICE_LICENSE when arriving here { diff --git a/indra/newview/llfloateravatarlist.cpp b/indra/newview/llfloateravatarlist.cpp index 158d69b37..51122e51b 100644 --- a/indra/newview/llfloateravatarlist.cpp +++ b/indra/newview/llfloateravatarlist.cpp @@ -172,7 +172,8 @@ void LLAvatarListEntry::processProperties(void* data, EAvatarProcessorType type) { using namespace boost::gregorian; int year, month, day; - if (sscanf(pAvatarData->born_on.c_str(),"%d/%d/%d",&month,&day,&year) == 3) + const auto born = pAvatarData->born_on; + if (!born.empty() && sscanf(born.c_str(),"%d/%d/%d",&month,&day,&year) == 3) try { mAge = (day_clock::local_day() - date(year, month, day)).days(); @@ -187,7 +188,7 @@ void LLAvatarListEntry::processProperties(void* data, EAvatarProcessorType type) } else // Something failed, resend request { - LL_WARNS() << "Failed to extract age from APT_PROPERTIES for " << mID << ", received \"" << pAvatarData->born_on << "\". Requesting properties again." << LL_ENDL; + LL_WARNS() << "Failed to extract age from APT_PROPERTIES for " << mID << ", received \"" << born << "\". Requesting properties again." << LL_ENDL; inst.sendAvatarPropertiesRequest(mID); } } @@ -258,7 +259,7 @@ LLFloaterAvatarList::~LLFloaterAvatarList() { mCleanup = true; LLSD sort; - for (const auto& col : mAvatarList->getSortColumns()) + for (const auto& col : mAvatarList->getSortOrder()) { sort.append(mAvatarList->getColumn(col.first)->mName); sort.append(col.second); @@ -311,6 +312,42 @@ BOOL LLFloaterAvatarList::handleRightMouseDown(S32 x, S32 y, MASK mask) return LLFloater::handleRightMouseDown(x, y, mask); } +bool is_nearby(const LLUUID& id) +{ + if (id.isNull()) return false; + if (const auto inst = LLFloaterAvatarList::getIfExists()) + return inst->getAvatarEntry(id); + uuid_vec_t avatars; + LLWorld::instance().getAvatars(&avatars); + return std::find(avatars.begin(), avatars.end(), id) != avatars.end(); +} + +void track_av(const LLUUID& id) +{ + if (auto inst = LLFloaterAvatarList::getIfExists()) + if (inst->getAvatarEntry(id)) + { + inst->trackAvatar(id); + return; + } + + LLWorld::pos_map_t avatars; + LLWorld::instance().getAvatars(&avatars); + LLTracker::trackLocation(avatars[id], LLStringUtil::null, LLStringUtil::null); +} + +void teleport_to(const LLUUID& id) +{ + if (auto entry = LLFloaterAvatarList::instanceExists() ? LLFloaterAvatarList::instance().getAvatarEntry(id) : nullptr) + gAgent.teleportViaLocation(entry->getPosition()); + else + { + LLWorld::pos_map_t avatars; + LLWorld::instance().getAvatars(&avatars); + gAgent.teleportViaLocation(avatars[id]); + } +} + static void cmd_profile(const LLAvatarListEntry* entry); static void cmd_toggle_mark(LLAvatarListEntry* entry); static void cmd_ar(const LLAvatarListEntry* entry); @@ -368,7 +405,7 @@ namespace { bool handleEvent(LLPointer event, const LLSD& userdata) { - LLFloaterAvatarList::instance().doCommand(cmd_teleport, true); + teleport_to(get_focused_list_id_selected()); return true; } }; @@ -387,13 +424,13 @@ void addMenu(view_listener_t* menu, const std::string& name); void add_radar_listeners() { - addMenu(new RadarTrack(), "Radar.Track"); - addMenu(new RadarMark(), "Radar.Mark"); - addMenu(new RadarFocus(), "Radar.Focus"); - addMenu(new RadarFocusPrev(), "Radar.FocusPrev"); - addMenu(new RadarFocusNext(), "Radar.FocusNext"); - addMenu(new RadarTeleportTo(), "Radar.TeleportTo"); - addMenu(new RadarAnnounceKeys(), "Radar.AnnounceKeys"); + addMenu(new RadarTrack, "Radar.Track"); + addMenu(new RadarMark, "Radar.Mark"); + addMenu(new RadarFocus, "Radar.Focus"); + addMenu(new RadarFocusPrev, "Radar.FocusPrev"); + addMenu(new RadarFocusNext, "Radar.FocusNext"); + addMenu(new RadarTeleportTo, "Radar.TeleportTo"); + addMenu(new RadarAnnounceKeys, "Radar.AnnounceKeys"); } BOOL LLFloaterAvatarList::postBuild() @@ -1098,8 +1135,11 @@ void LLFloaterAvatarList::onClickTrack() LLScrollListItem* item = mAvatarList->getFirstSelected(); if (!item) return; - LLUUID agent_id = item->getUUID(); + trackAvatar(item->getUUID()); +} +void LLFloaterAvatarList::trackAvatar(const LLUUID& agent_id) +{ if (mTracking && mTrackedAvatar == agent_id) { LLTracker::stopTracking(false); @@ -1430,7 +1470,7 @@ static void cmd_eject(const LLAvatarListEntry* entry) { send_eject(entry->getID static void cmd_ban(const LLAvatarListEntry* entry) { send_eject(entry->getID(), true); } static void cmd_estate_eject(const LLAvatarListEntry* entry){ send_estate_message("kickestate", {entry->getID().asString()}); } static void cmd_estate_tp_home(const LLAvatarListEntry* entry){ send_estate_message("teleporthomeuser", {gAgentID.asString(), entry->getID().asString()}); } -static void cmd_estate_ban(const LLAvatarListEntry* entry) { LLPanelEstateInfo::sendEstateAccessDelta(ESTATE_ACCESS_BANNED_AGENT_ADD | ESTATE_ACCESS_ALLOWED_AGENT_REMOVE | ESTATE_ACCESS_NO_REPLY, entry->getID()); } +static void cmd_estate_ban(const LLAvatarListEntry* entry) { LLPanelEstateAccess::sendEstateAccessDelta(ESTATE_ACCESS_BANNED_AGENT_ADD | ESTATE_ACCESS_ALLOWED_AGENT_REMOVE | ESTATE_ACCESS_NO_REPLY, entry->getID()); } void LLFloaterAvatarList::doCommand(avlist_command_t func, bool single/*=false*/) const { diff --git a/indra/newview/llfloateravatarlist.h b/indra/newview/llfloateravatarlist.h index 233eb4618..480e52f52 100644 --- a/indra/newview/llfloateravatarlist.h +++ b/indra/newview/llfloateravatarlist.h @@ -266,6 +266,7 @@ public: void focusOnNext(bool marked_only); void refreshTracker(); + void trackAvatar(const LLUUID& agent_id); void trackAvatar(const LLAvatarListEntry* entry) const; /** diff --git a/indra/newview/llfloateravatarpicker.cpp b/indra/newview/llfloateravatarpicker.cpp index 50669c006..6c5e22775 100644 --- a/indra/newview/llfloateravatarpicker.cpp +++ b/indra/newview/llfloateravatarpicker.cpp @@ -257,16 +257,21 @@ void LLFloaterAvatarPicker::onBtnSelect() uuid_vec_t avatar_ids; std::vector avatar_names; getSelectedAvatarData(list, avatar_ids, avatar_names); + if (mCloseOnSelect) // Singu Note: Close before callback if we get here first, makes potential next dialog floater position correctly + { + mCloseOnSelect = FALSE; + close(); + } mSelectionCallback(avatar_ids, avatar_names); } } getChild("SearchResults")->deselectAllItems(TRUE); getChild("NearMe")->deselectAllItems(TRUE); getChild("Friends")->deselectAllItems(TRUE); - if(mCloseOnSelect) + if (mCloseOnSelect) { mCloseOnSelect = FALSE; - close(); + close(); } } diff --git a/indra/newview/llfloaterbanduration.cpp b/indra/newview/llfloaterbanduration.cpp new file mode 100644 index 000000000..3555cd846 --- /dev/null +++ b/indra/newview/llfloaterbanduration.cpp @@ -0,0 +1,92 @@ +/** +* @file llfloaterbanduration.cpp +* +* $LicenseInfo:firstyear=2004&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2018, 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 "llfloaterbanduration.h" + +#include "llcombobox.h" +#include "llspinctrl.h" +#include "lluictrlfactory.h" + +LLFloaterBanDuration::LLFloaterBanDuration(const LLSD& target) : LLFloater() +{ + LLUICtrlFactory::instance().buildFloater(this, "floater_ban_duration.xml"); +} + +BOOL LLFloaterBanDuration::postBuild() +{ + childSetAction("ok_btn", boost::bind(&LLFloaterBanDuration::onClickBan, this)); + childSetAction("cancel_btn", boost::bind(&LLFloaterBanDuration::close, this, false)); + + auto combo = getChild("ban_duration_combo"); + combo->setCommitCallback(boost::bind(&LLFloaterBanDuration::onClickCombo, this, _2, getChild("ban_duration"))); + combo->onCommit(); + + return TRUE; +} + +LLFloaterBanDuration* LLFloaterBanDuration::show(select_callback_t callback, const uuid_vec_t& ids) +{ + LLFloaterBanDuration* floater = showInstance(); + if (!floater) + { + LL_WARNS() << "Cannot instantiate ban duration floater" << LL_ENDL; + return nullptr; + } + + floater->mSelectionCallback = callback; + floater->mAvatar_ids = ids; + + return floater; +} + +void LLFloaterBanDuration::onClickCombo(const LLSD& val, LLUICtrl* duration) +{ + duration->setEnabled(val.asInteger() != 0); +} + +void LLFloaterBanDuration::onClickBan() +{ + if (mSelectionCallback) + { + S32 time = 0; + if (auto type = getChild("ban_duration_combo")->getValue().asInteger()) + { + LLSpinCtrl* duration_spin = getChild("ban_duration"); + if (duration_spin) + { + time = (duration_spin->getValue().asInteger() * 3600); + if (type > 1) + { + time *= type == 2 ? 24 : type == 3 ? 168 : 730; + } + time += LLDate::now().secondsSinceEpoch(); + } + } + mSelectionCallback(mAvatar_ids, time); + } + close(); +} + diff --git a/indra/newview/llfloaterbanduration.h b/indra/newview/llfloaterbanduration.h new file mode 100644 index 000000000..75b063ec6 --- /dev/null +++ b/indra/newview/llfloaterbanduration.h @@ -0,0 +1,52 @@ +/** +* @file llfloaterbanduration.h +* +* $LicenseInfo:firstyear=2004&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2018, 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_FLOATERBANDURATION_H +#define LL_FLOATERBANDURATION_H + +#include "llfloater.h" + +class LLFloaterBanDuration : public LLFloater +, public LLFloaterSingleton +{ + typedef std::function select_callback_t; + +public: + LLFloaterBanDuration(const LLSD& target); + BOOL postBuild() override; + static LLFloaterBanDuration* show(select_callback_t callback, const uuid_vec_t& ids); + +private: + ~LLFloaterBanDuration() {}; + void onClickBan(); + void onClickCombo(const LLSD&, LLUICtrl*); + + uuid_vec_t mAvatar_ids; + select_callback_t mSelectionCallback; +}; + +#endif // LL_FLOATERBANDURATION_H + diff --git a/indra/newview/llfloaterchat.cpp b/indra/newview/llfloaterchat.cpp index 49930a925..c1bf51012 100644 --- a/indra/newview/llfloaterchat.cpp +++ b/indra/newview/llfloaterchat.cpp @@ -510,7 +510,7 @@ LLColor4 get_text_color(const LLChat& chat, bool from_im) } static const LLCachedControl sKeywordsChangeColor(gSavedPerAccountSettings, "KeywordsChangeColor", false); - if (sKeywordsChangeColor && gAgentID != chat.mFromID && chat.mSourceType != CHAT_SOURCE_SYSTEM && AscentKeyword::hasKeyword(boost::starts_with(chat.mText, chat.mFromName) ? chat.mText.substr(chat.mFromName.length()) : chat.mText, 1)) + if (sKeywordsChangeColor && gAgentID != chat.mFromID && AscentKeyword::hasKeyword((chat.mSourceType != CHAT_SOURCE_SYSTEM && boost::starts_with(chat.mText, chat.mFromName)) ? chat.mText.substr(chat.mFromName.length()) : chat.mText, 1)) { static const LLCachedControl sKeywordsColor(gSavedPerAccountSettings, "KeywordsColor", LLColor4(1.f, 1.f, 1.f, 1.f)); text_color = sKeywordsColor; diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp index 064fee823..59f2b5049 100644 --- a/indra/newview/llfloaterland.cpp +++ b/indra/newview/llfloaterland.cpp @@ -52,6 +52,7 @@ #include "llcombobox.h" #include "llfloaterauction.h" #include "llfloateravatarpicker.h" +#include "llfloaterbanduration.h" #include "llfloatergroups.h" #include "llfloaterscriptlimits.h" #include "llgroupactions.h" @@ -220,7 +221,6 @@ void LLFloaterLand::onOpen() refresh(); } - // virtual void LLFloaterLand::onClose(bool app_quitting) { @@ -471,6 +471,13 @@ BOOL LLPanelLandGeneral::postBuild() mBtnBuyLand = getChild("Buy Land..."); mBtnBuyLand->setClickedCallback(onClickBuyLand, (void*)&BUY_PERSONAL_LAND); + + + if(gDisconnected) + { + return TRUE; + } + // note: on region change this will not be re checked, should not matter on Agni as // 99% of the time all regions will return the same caps. In case of an erroneous setting // to enabled the floater will just throw an error when trying to get it's cap @@ -584,6 +591,11 @@ void LLPanelLandGeneral::refresh() mBtnReleaseLand->setEnabled(FALSE); mBtnReclaimLand->setEnabled(FALSE); mBtnBuyPass->setEnabled(FALSE); + + if(gDisconnected) + { + return; + } } else { @@ -591,7 +603,7 @@ void LLPanelLandGeneral::refresh() BOOL is_leased = (LLParcel::OS_LEASED == parcel->getOwnershipStatus()); BOOL region_xfer = FALSE; if(regionp - && !regionp->getRegionFlag(REGION_FLAGS_BLOCK_LAND_RESELL)) + && !(regionp->getRegionFlag(REGION_FLAGS_BLOCK_LAND_RESELL))) { region_xfer = TRUE; } @@ -1245,7 +1257,7 @@ void LLPanelLandObjects::refresh() mOwnerList->deleteAllItems(); mOwnerList->setEnabled(FALSE); - if (!parcel) + if (!parcel || gDisconnected) { mSWTotalObjects->setTextArg("[COUNT]", llformat("%d", 0)); mSWTotalObjects->setTextArg("[TOTAL]", llformat("%d", 0)); @@ -1619,23 +1631,22 @@ void LLPanelLandObjects::processParcelObjectOwnersReply(LLMessageSystem *msg, vo { msg->getU32("DataExtended", "TimeStamp", most_recent_time, i); } + if (owner_id.isNull()) { continue; } - BOOL in_sim = (std::find(avatar_ids.begin(), avatar_ids.end(), owner_id) != avatar_ids.end()); - LLNameListCtrl::NameItem item_params; item_params.value = owner_id; - item_params.target = is_group_owned ? LLNameListCtrl::GROUP : LLNameListCtrl::INDIVIDUAL; + item_params.target = is_group_owned ? LLNameListItem::GROUP : LLNameListItem::INDIVIDUAL; if (is_group_owned) { item_params.columns.add().type("icon").value(self->mIconGroup->getName()).column("type"); item_params.columns.add().value(OWNER_GROUP).font(FONT).column("online_status"); } - else if (in_sim) + else if (std::find(avatar_ids.begin(), avatar_ids.end(), owner_id) != avatar_ids.end()) { item_params.columns.add().type("icon").value(self->mIconAvatarInSim->getName()).column("type"); item_params.columns.add().value(OWNER_INSIM).font(FONT).column("online_status"); @@ -1661,10 +1672,10 @@ void LLPanelLandObjects::processParcelObjectOwnersReply(LLMessageSystem *msg, vo item_params.columns.add().value(LLDate((time_t)most_recent_time)).font(FONT).column("mostrecent").type("date"); self->mOwnerList->addNameItemRow(item_params); - LL_DEBUGS() << "object owner " << owner_id << " (" << (is_group_owned ? "group" : "agent") << ") owns " << object_count << " objects." << LL_ENDL; } + // check for no results if (0 == self->mOwnerList->getItemCount()) { @@ -1842,10 +1853,15 @@ void LLPanelLandObjects::onCommitClean(LLUICtrl *caller, void* user_data) LLParcel* parcel = lop->mParcel->getParcel(); if (parcel) { - lop->mOtherTime = atoi(lop->mCleanOtherObjectsTime->getText().c_str()); + S32 return_time = atoi(lop->mCleanOtherObjectsTime->getText().c_str()); + // Only send return time if it has changed + if (return_time != lop->mOtherTime) + { + lop->mOtherTime = return_time; - parcel->setCleanOtherTime(lop->mOtherTime); - send_other_clean_time_message(parcel->getLocalID(), lop->mOtherTime); + parcel->setCleanOtherTime(lop->mOtherTime); + send_other_clean_time_message(parcel->getLocalID(), lop->mOtherTime); + } } } @@ -2014,7 +2030,7 @@ void LLPanelLandOptions::refresh() refreshSearch(); LLParcel *parcel = mParcel->getParcel(); - if (!parcel) + if (!parcel || gDisconnected) { mCheckEditObjects ->set(FALSE); mCheckEditObjects ->setEnabled(FALSE); @@ -2203,7 +2219,7 @@ void LLPanelLandOptions::draw() void LLPanelLandOptions::refreshSearch() { LLParcel *parcel = mParcel->getParcel(); - if (!parcel) + if (!parcel || gDisconnected) { mCheckShowDirectory->set(FALSE); mCheckShowDirectory->setEnabled(FALSE); @@ -2499,127 +2515,120 @@ void LLPanelLandAccess::refresh() LLParcel *parcel = mParcel->getParcel(); // Display options - if (parcel) + if (parcel && !gDisconnected) { BOOL use_access_list = parcel->getParcelFlag(PF_USE_ACCESS_LIST); BOOL use_group = parcel->getParcelFlag(PF_USE_ACCESS_GROUP); BOOL public_access = !use_access_list && !use_group; - getChild("public_access")->setValue(public_access ); - getChild("GroupCheck")->setValue(use_group ); + getChild("public_access")->setValue(public_access); + getChild("GroupCheck")->setValue(use_group); std::string group_name; gCacheName->getGroupName(parcel->getGroupID(), group_name); getChild("GroupCheck")->setLabelArg("[GROUP]", group_name ); - + + const auto always = getString("Always"); + + static const LLCachedControl date("ShortDateFormat"); + static const LLCachedControl time("LongTimeFormat"); + const auto time_format = date() + ' ' + time(); + // Allow list if (mListAccess) { // Clear the sort order so we don't re-sort on every add. + const auto order = mListAccess->getSortOrder(); mListAccess->clearSortOrder(); mListAccess->deleteAllItems(); S32 count = parcel->mAccessList.size(); - getChild("AccessList")->setToolTipArg(LLStringExplicit("[LISTED]"), llformat("%d",count)); - getChild("AccessList")->setToolTipArg(LLStringExplicit("[MAX]"), llformat("%d",PARCEL_MAX_ACCESS_LIST)); + getChild("AllowedText")->setTextArg("[COUNT]", llformat("%d",count)); + getChild("AllowedText")->setTextArg("[MAX]", llformat("%d",PARCEL_MAX_ACCESS_LIST)); + + mListAccess->setToolTipArg(LLStringExplicit("[LISTED]"), llformat("%d",count)); + mListAccess->setToolTipArg(LLStringExplicit("[MAX]"), llformat("%d",PARCEL_MAX_ACCESS_LIST)); for (access_map_const_iterator cit = parcel->mAccessList.begin(); cit != parcel->mAccessList.end(); ++cit) { const LLAccessEntry& entry = (*cit).second; - std::string suffix; + LLSD item; + item["id"] = entry.mID; + LLSD& columns = item["columns"]; + columns[0]["column"] = "name"; // to be populated later + columns[1]["column"] = "duration"; if (entry.mTime != 0) { - S32 now = time(NULL); - S32 seconds = entry.mTime - now; - if (seconds < 0) seconds = 0; - suffix.assign(" ("); - if (seconds >= 120) - { - std::string buf = llformat("%d ", (seconds/60)) + getString("minutes"); - suffix.append(buf); - } - else if (seconds >= 60) - { - suffix.append(getString("1_minute")); - } - else if (seconds == 1) - { - suffix.append(getString("1_second")); - } - else - { - std::string buf = llformat("%d ", seconds) + getString("seconds"); - suffix.append(buf); - } - suffix.append(" " + getString("remaining") + ")"); + columns[1]["type"] = "date"; + columns[1]["format"] = time_format; + columns[1]["value"] = LLDate(entry.mTime); } - mListAccess->addNameItem(entry.mID, ADD_SORTED, TRUE, suffix); + else + { + columns[1]["value"] = always; + } + mListAccess->addElement(item); } - mListAccess->sortByName(TRUE); + mListAccess->setSortOrder(order); } // Ban List if(mListBanned) { // Clear the sort order so we don't re-sort on every add. + const auto order = mListBanned->getSortOrder(); mListBanned->clearSortOrder(); mListBanned->deleteAllItems(); S32 count = parcel->mBanList.size(); + getChild("BanCheck")->setTextArg("[COUNT]", llformat("%d",count)); + getChild("BanCheck")->setTextArg("[MAX]", llformat("%d",PARCEL_MAX_ACCESS_LIST)); - getChild("BannedList")->setToolTipArg(LLStringExplicit("[LISTED]"), llformat("%d",count)); - getChild("BannedList")->setToolTipArg(LLStringExplicit("[MAX]"), llformat("%d",PARCEL_MAX_ACCESS_LIST)); + mListBanned->setToolTipArg(LLStringExplicit("[LISTED]"), llformat("%d",count)); + mListBanned->setToolTipArg(LLStringExplicit("[MAX]"), llformat("%d",PARCEL_MAX_ACCESS_LIST)); for (access_map_const_iterator cit = parcel->mBanList.begin(); cit != parcel->mBanList.end(); ++cit) { const LLAccessEntry& entry = (*cit).second; - std::string suffix; + LLSD item; + item["id"] = entry.mID; + LLSD& columns = item["columns"]; + columns[0]["column"] = "name"; // to be populated later + columns[1]["column"] = "duration"; if (entry.mTime != 0) { - S32 now = time(NULL); - S32 seconds = entry.mTime - now; - if (seconds < 0) seconds = 0; - suffix.assign(" ("); - if (seconds >= 120) - { - std::string buf = llformat("%d ", (seconds/60)) + getString("minutes"); - suffix.append(buf); - } - else if (seconds >= 60) - { - suffix.append(getString("1_minute")); - } - else if (seconds == 1) - { - suffix.append(getString("1_second")); - } - else - { - std::string buf = llformat("%d ", seconds) + getString("seconds"); - suffix.append(buf); - } - suffix.append(" " + getString("remaining") + ")"); + columns[1]["type"] = "date"; + columns[1]["format"] = time_format; + columns[1]["value"] = LLDate(entry.mTime); } - mListBanned->addNameItem(entry.mID, ADD_SORTED, TRUE, suffix); + else + { + columns[1]["value"] = always; + } + mListBanned->addElement(item); } - mListBanned->sortByName(TRUE); + mListBanned->setSortOrder(order); } if(parcel->getRegionDenyAnonymousOverride()) { getChild("limit_payment")->setValue(TRUE); + getChild("limit_payment")->setLabelArg("[ESTATE_PAYMENT_LIMIT]", getString("access_estate_defined") ); } else { getChild("limit_payment")->setValue((parcel->getParcelFlag(PF_DENY_ANONYMOUS))); + getChild("limit_payment")->setLabelArg("[ESTATE_PAYMENT_LIMIT]", std::string() ); } if(parcel->getRegionDenyAgeUnverifiedOverride()) { getChild("limit_age_verified")->setValue(TRUE); + getChild("limit_age_verified")->setLabelArg("[ESTATE_AGE_LIMIT]", getString("access_estate_defined") ); } else { getChild("limit_age_verified")->setValue((parcel->getParcelFlag(PF_DENY_AGEUNVERIFIED))); + getChild("limit_age_verified")->setLabelArg("[ESTATE_AGE_LIMIT]", std::string() ); } BOOL use_pass = parcel->getParcelFlag(PF_USE_PASS_LIST); @@ -2650,10 +2659,10 @@ void LLPanelLandAccess::refresh() getChild("PassCheck")->setValue(FALSE); getChild("PriceSpin")->setValue((F32)PARCEL_PASS_PRICE_DEFAULT); getChild("HoursSpin")->setValue(PARCEL_PASS_HOURS_DEFAULT ); - getChild("AccessList")->setToolTipArg(LLStringExplicit("[LISTED]"), llformat("%d",0)); - getChild("AccessList")->setToolTipArg(LLStringExplicit("[MAX]"), llformat("%d",0)); - getChild("BannedList")->setToolTipArg(LLStringExplicit("[LISTED]"), llformat("%d",0)); - getChild("BannedList")->setToolTipArg(LLStringExplicit("[MAX]"), llformat("%d",0)); + mListAccess->setToolTipArg(LLStringExplicit("[LISTED]"), llformat("%d",0)); + mListAccess->setToolTipArg(LLStringExplicit("[MAX]"), llformat("%d",0)); + mListBanned->setToolTipArg(LLStringExplicit("[LISTED]"), llformat("%d",0)); + mListBanned->setToolTipArg(LLStringExplicit("[MAX]"), llformat("%d",0)); } } @@ -2667,11 +2676,15 @@ void LLPanelLandAccess::refresh_ui() getChildView("pass_combo")->setEnabled(FALSE); getChildView("PriceSpin")->setEnabled(FALSE); getChildView("HoursSpin")->setEnabled(FALSE); - getChildView("AccessList")->setEnabled(FALSE); - getChildView("BannedList")->setEnabled(FALSE); + mListAccess->setEnabled(FALSE); + mListBanned->setEnabled(FALSE); + getChildView("add_allowed")->setEnabled(FALSE); + getChildView("remove_allowed")->setEnabled(FALSE); + getChildView("add_banned")->setEnabled(FALSE); + getChildView("remove_banned")->setEnabled(FALSE); LLParcel *parcel = mParcel->getParcel(); - if (parcel) + if (parcel && !gDisconnected) { BOOL can_manage_allowed = LLViewerParcelMgr::isParcelModifiableByAgent(parcel, GP_LAND_MANAGE_ALLOWED); BOOL can_manage_banned = LLViewerParcelMgr::isParcelModifiableByAgent(parcel, GP_LAND_MANAGE_BANNED); @@ -2710,7 +2723,7 @@ void LLPanelLandAccess::refresh_ui() getChildView("GroupCheck")->setEnabled(FALSE); getChildView("PassCheck")->setEnabled(FALSE); getChildView("pass_combo")->setEnabled(FALSE); - getChildView("AccessList")->setEnabled(FALSE); + mListAccess->setEnabled(FALSE); } else { @@ -2719,7 +2732,7 @@ void LLPanelLandAccess::refresh_ui() std::string group_name; if (gCacheName->getGroupName(parcel->getGroupID(), group_name)) - { + { getChildView("GroupCheck")->setEnabled(can_manage_allowed); } BOOL sell_passes = getChild("PassCheck")->getValue().asBoolean(); @@ -2731,13 +2744,13 @@ void LLPanelLandAccess::refresh_ui() getChildView("HoursSpin")->setEnabled(can_manage_allowed); } } - getChildView("AccessList")->setEnabled(true/*can_manage_allowed*/); + mListAccess->setEnabled(true/*can_manage_allowed*/); S32 allowed_list_count = parcel->mAccessList.size(); getChildView("add_allowed")->setEnabled(can_manage_allowed && allowed_list_count < PARCEL_MAX_ACCESS_LIST); BOOL has_selected = (mListAccess && mListAccess->getSelectionInterface()->getFirstSelectedIndex() >= 0); getChildView("remove_allowed")->setEnabled(can_manage_allowed && has_selected); - getChildView("BannedList")->setEnabled(true/*can_manage_banned*/); + mListBanned->setEnabled(true/*can_manage_banned*/); S32 banned_list_count = parcel->mBanList.size(); getChildView("add_banned")->setEnabled(can_manage_banned && banned_list_count < PARCEL_MAX_ACCESS_LIST); has_selected = (mListBanned && mListBanned->getSelectionInterface()->getFirstSelectedIndex() >= 0); @@ -2779,12 +2792,12 @@ void LLPanelLandAccess::onCommitPublicAccess(LLUICtrl *ctrl, void *userdata) // If we disabled public access, enable group access by default (if applicable) BOOL public_access = self->getChild("public_access")->getValue().asBoolean(); - if (public_access == FALSE) + if (!public_access) { std::string group_name; if (gCacheName->getGroupName(parcel->getGroupID(), group_name)) { - self->getChild("GroupCheck")->setValue(public_access ? FALSE : TRUE); + self->getChild("GroupCheck")->setValue(true); } } @@ -2893,7 +2906,7 @@ void LLPanelLandAccess::onClickAddAccess() { LLFloater* root_floater = gFloaterView->getParentFloater(this); LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show( - boost::bind(&LLPanelLandAccess::callbackAvatarCBAccess, this, _1)); + boost::bind(&LLPanelLandAccess::callbackAvatarCBAccess, this, _1), true, true); if (picker) { root_floater->addDependentFloater(picker); @@ -2902,17 +2915,29 @@ void LLPanelLandAccess::onClickAddAccess() void LLPanelLandAccess::callbackAvatarCBAccess(const uuid_vec_t& ids) { - if (!ids.empty()) + LLParcel* parcel = mParcel->getParcel(); + if (!parcel) return; + + U32 lists_to_update = 0; + + for (const auto& id : ids) { - LLUUID id = ids[0]; - LLParcel* parcel = mParcel->getParcel(); - if (parcel) + if (parcel->addToAccessList(id, 0)) { - parcel->addToAccessList(id, 0); - LLViewerParcelMgr::getInstance()->sendParcelAccessListUpdate(AL_ACCESS); - refresh(); + lists_to_update |= AL_ACCESS; + // agent was successfully added to access list + // but we also need to check ban list to ensure that agent will not be in two lists simultaneously + if(parcel->removeFromBanList(id)) + { + lists_to_update |= AL_BAN; + } } } + if (lists_to_update) + { + LLViewerParcelMgr::getInstance()->sendParcelAccessListUpdate(lists_to_update); + refresh(); + } } // static @@ -2942,7 +2967,7 @@ void LLPanelLandAccess::onClickAddBanned() { LLFloater* root_floater = gFloaterView->getParentFloater(this); LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show( - boost::bind(&LLPanelLandAccess::callbackAvatarCBBanned, this, _1)); + boost::bind(&LLPanelLandAccess::callbackAvatarCBBanned, this, _1), true, true); if (picker) { root_floater->addDependentFloater(picker); @@ -2951,17 +2976,40 @@ void LLPanelLandAccess::onClickAddBanned() void LLPanelLandAccess::callbackAvatarCBBanned(const uuid_vec_t& ids) { - if (!ids.empty()) + LLFloater* root_floater = gFloaterView->getParentFloater(this); + LLFloaterBanDuration* duration_floater = LLFloaterBanDuration::show( + boost::bind(&LLPanelLandAccess::callbackAvatarCBBanned2, this, _1, _2), ids); + if (duration_floater) { - LLUUID id = ids[0]; - LLParcel* parcel = mParcel->getParcel(); - if (parcel) + root_floater->addDependentFloater(duration_floater); + } +} + +void LLPanelLandAccess::callbackAvatarCBBanned2(const uuid_vec_t& ids, S32 duration) +{ + LLParcel* parcel = mParcel->getParcel(); + if (!parcel) return; + + U32 lists_to_update = 0; + + for (const auto& id : ids) + { + if (parcel->addToBanList(id, duration)) { - parcel->addToBanList(id, 0); - LLViewerParcelMgr::getInstance()->sendParcelAccessListUpdate(AL_BAN); - refresh(); + lists_to_update |= AL_BAN; + // agent was successfully added to ban list + // but we also need to check access list to ensure that agent will not be in two lists simultaneously + if(parcel->removeFromAccessList(id)) + { + lists_to_update |= AL_ACCESS; + } } } + if (lists_to_update) + { + LLViewerParcelMgr::getInstance()->sendParcelAccessListUpdate(lists_to_update); + refresh(); + } } // static @@ -3010,7 +3058,7 @@ BOOL LLPanelLandCovenant::postBuild() void LLPanelLandCovenant::refresh() { LLViewerRegion* region = LLViewerParcelMgr::getInstance()->getSelectionRegion(); - if(!region) return; + if(!region || gDisconnected) return; LLTextBox* region_name = getChild("region_name_text"); if (region_name) diff --git a/indra/newview/llfloaterland.h b/indra/newview/llfloaterland.h index 1329c60df..eb0cefd7f 100644 --- a/indra/newview/llfloaterland.h +++ b/indra/newview/llfloaterland.h @@ -384,6 +384,7 @@ public: void onClickAddAccess(); void onClickAddBanned(); void callbackAvatarCBBanned(const uuid_vec_t& ids); + void callbackAvatarCBBanned2(const uuid_vec_t& ids, S32 duration); void callbackAvatarCBAccess(const uuid_vec_t& ids); protected: diff --git a/indra/newview/llfloatermute.cpp b/indra/newview/llfloatermute.cpp index cced63ab1..97325f0b2 100644 --- a/indra/newview/llfloatermute.cpp +++ b/indra/newview/llfloatermute.cpp @@ -41,6 +41,7 @@ // project include #include "llfloateravatarpicker.h" +#include "llgroupactions.h" #include "llmutelist.h" #include "llnamelistctrl.h" @@ -248,20 +249,20 @@ void LLFloaterMute::refreshMuteList() { case LLMute::GROUP: icon_column.value = mGroupIcon->getName(); - element.target = LLNameListCtrl::GROUP; + element.target = LLNameListItem::GROUP; break; case LLMute::AGENT: icon_column.value = mAvatarIcon->getName(); - element.target = LLNameListCtrl::INDIVIDUAL; + element.target = LLNameListItem::INDIVIDUAL; break; case LLMute::OBJECT: icon_column.value = mObjectIcon->getName(); - element.target = LLNameListCtrl::SPECIAL; + element.target = LLNameListItem::SPECIAL; break; case LLMute::BY_NAME: default: icon_column.value = mNameIcon->getName(); - element.target = LLNameListCtrl::SPECIAL; + element.target = LLNameListItem::SPECIAL; break; } diff --git a/indra/newview/llfloatermute.h b/indra/newview/llfloatermute.h index 1a04ae198..b9a116528 100644 --- a/indra/newview/llfloatermute.h +++ b/indra/newview/llfloatermute.h @@ -72,6 +72,7 @@ private: void onPickUser(const uuid_vec_t& ids, const std::vector& names); static void onClickMuteByName(void*); static void callbackMuteByName(const std::string& text, void*); + void showProfile() const; private: LLNameListCtrl* mMuteList; diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index 9b24c620f..fc4818e32 100644 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -53,6 +53,7 @@ #include "llfloateravatarpicker.h" #include "llbutton.h" #include "llcheckboxctrl.h" +#include "llclipboard.h" #include "llcombobox.h" #include "lldaycyclemanager.h" #include "llenvmanager.h" @@ -95,6 +96,8 @@ const S32 TERRAIN_TEXTURE_COUNT = 4; const S32 CORNER_COUNT = 4; +const U32 MAX_LISTED_NAMES = 100; + ///---------------------------------------------------------------------------- /// Local class declaration ///---------------------------------------------------------------------------- @@ -223,6 +226,11 @@ BOOL LLFloaterRegionInfo::postBuild() LLUICtrlFactory::getInstance()->buildPanel(panel, "panel_region_estate.xml"); mTab->addTabPanel(panel, panel->getLabel(), FALSE); + panel = new LLPanelEstateAccess; + mInfoPanels.push_back(panel); + LLUICtrlFactory::getInstance()->buildPanel(panel, "panel_region_access.xml"); + mTab->addTabPanel(panel, panel->getLabel(), FALSE); + panel = new LLPanelEstateCovenant; mInfoPanels.push_back(panel); LLUICtrlFactory::getInstance()->buildPanel(panel, "panel_region_covenant.xml"); @@ -271,9 +279,24 @@ void LLFloaterRegionInfo::onOpen() refreshFromRegion(gAgent.getRegion()); requestRegionInfo(); requestMeshRezInfo(); + + if (!mGodLevelChangeSlot.connected()) + { + mGodLevelChangeSlot = gAgent.registerGodLevelChanageListener(boost::bind(&LLFloaterRegionInfo::onGodLevelChange, this, _1)); + } + LLFloater::onOpen(); } +void LLFloaterRegionInfo::onClose(bool app_quitting) +{ + if (mGodLevelChangeSlot.connected()) + { + mGodLevelChangeSlot.disconnect(); + } + LLFloater::onClose(app_quitting); +} + // static void LLFloaterRegionInfo::requestRegionInfo() { @@ -283,6 +306,9 @@ void LLFloaterRegionInfo::requestRegionInfo() tab->getChild("Debug")->setCtrlsEnabled(FALSE); tab->getChild("Terrain")->setCtrlsEnabled(FALSE); tab->getChild("Estate")->setCtrlsEnabled(FALSE); + auto panel = tab->getChild("Access"); + panel->setCtrlsEnabled(FALSE); + panel->getChildView("tabs")->setEnabled(true); // Must allow anyone to request the RegionInfo data // so non-owners/non-gods can see the values. @@ -310,8 +336,7 @@ void LLFloaterRegionInfo::processEstateOwnerRequest(LLMessageSystem* msg,void**) LLPanelEstateInfo::initDispatch(dispatch); } - LLTabContainer* tab = floater->getChild("region_panels"); - LLPanelEstateInfo* panel = (LLPanelEstateInfo*)tab->getChild("Estate"); + LLPanelEstateInfo* panel = LLFloaterRegionInfo::getPanelEstate(); // unpack the message std::string request; @@ -327,7 +352,10 @@ void LLFloaterRegionInfo::processEstateOwnerRequest(LLMessageSystem* msg,void**) //dispatch the message dispatch.dispatch(request, invoice, strings); - panel->updateControls(gAgent.getRegion()); + if (panel) + { + panel->updateControls(gAgent.getRegion()); + } } @@ -466,6 +494,16 @@ LLPanelEstateInfo* LLFloaterRegionInfo::getPanelEstate() return panel; } +// static +LLPanelEstateAccess* LLFloaterRegionInfo::getPanelAccess() +{ + LLFloaterRegionInfo* floater = LLFloaterRegionInfo::getInstance(); + if (!floater) return NULL; + LLTabContainer* tab = floater->getChild("region_panels"); + LLPanelEstateAccess* panel = (LLPanelEstateAccess*)tab->getChild("Access"); + return panel; +} + // static LLPanelEstateCovenant* LLFloaterRegionInfo::getPanelCovenant() { @@ -525,6 +563,14 @@ void LLFloaterRegionInfo::refresh() } } +void LLFloaterRegionInfo::onGodLevelChange(U8 god_level) +{ + LLFloaterRegionInfo* floater = getInstance(); + if (floater && floater->getVisible()) + { + refreshFromRegion(gAgent.getRegion()); + } +} ///---------------------------------------------------------------------------- /// Local class implementation @@ -1484,10 +1530,6 @@ void LLPanelEstateInfo::initDispatch(LLDispatcher& dispatch) { std::string name; -// name.assign("setowner"); -// static LLDispatchSetEstateOwner set_owner; -// dispatch.addHandler(name, &set_owner); - name.assign("estateupdateinfo"); static LLDispatchEstateUpdateInfo estate_update_info; dispatch.addHandler(name, &estate_update_info); @@ -1499,124 +1541,6 @@ void LLPanelEstateInfo::initDispatch(LLDispatcher& dispatch) estate_dispatch_initialized = true; } -//--------------------------------------------------------------------------- -// Add/Remove estate access button callbacks -//--------------------------------------------------------------------------- -void LLPanelEstateInfo::onClickAddAllowedAgent() -{ - LLCtrlListInterface *list = childGetListInterface("allowed_avatar_name_list"); - if (!list) return; - if (list->getItemCount() >= ESTATE_MAX_ACCESS_IDS) - { - //args - - LLSD args; - args["MAX_AGENTS"] = llformat("%d",ESTATE_MAX_ACCESS_IDS); - LLNotificationsUtil::add("MaxAllowedAgentOnRegion", args); - return; - } - accessAddCore(ESTATE_ACCESS_ALLOWED_AGENT_ADD, "EstateAllowedAgentAdd"); -} - -void LLPanelEstateInfo::onClickRemoveAllowedAgent() -{ - accessRemoveCore(ESTATE_ACCESS_ALLOWED_AGENT_REMOVE, "EstateAllowedAgentRemove", "allowed_avatar_name_list"); -} - -void LLPanelEstateInfo::onClickAddAllowedGroup() -{ - LLCtrlListInterface *list = childGetListInterface("allowed_group_name_list"); - if (!list) return; - if (list->getItemCount() >= ESTATE_MAX_ACCESS_IDS) - { - LLSD args; - args["MAX_GROUPS"] = llformat("%d",ESTATE_MAX_ACCESS_IDS); - LLNotificationsUtil::add("MaxAllowedGroupsOnRegion", args); - return; - } - - LLNotification::Params params("ChangeLindenAccess"); - params.functor(boost::bind(&LLPanelEstateInfo::addAllowedGroup, this, _1, _2)); - if (isLindenEstate()) - { - LLNotifications::instance().add(params); - } - else - { - LLNotifications::instance().forceResponse(params, 0); - } -} - -bool LLPanelEstateInfo::addAllowedGroup(const LLSD& notification, const LLSD& response) -{ - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - if (option != 0) return false; - - LLFloater* parent_floater = gFloaterView->getParentFloater(this); - - LLFloaterGroupPicker* widget = LLFloaterGroupPicker::showInstance(LLSD(gAgent.getID())); - if (widget) - { - widget->removeNoneOption(); - widget->setSelectGroupCallback(boost::bind(&LLPanelEstateInfo::addAllowedGroup2, this, _1)); - if (parent_floater) - { - LLRect new_rect = gFloaterView->findNeighboringPosition(parent_floater, widget); - widget->setOrigin(new_rect.mLeft, new_rect.mBottom); - parent_floater->addDependentFloater(widget); - } - } - - return false; -} - -void LLPanelEstateInfo::onClickRemoveAllowedGroup() -{ - accessRemoveCore(ESTATE_ACCESS_ALLOWED_GROUP_REMOVE, "EstateAllowedGroupRemove", "allowed_group_name_list"); -} - -void LLPanelEstateInfo::onClickAddBannedAgent() -{ - LLCtrlListInterface *list = childGetListInterface("banned_avatar_name_list"); - if (!list) return; - if (list->getItemCount() >= ESTATE_MAX_ACCESS_IDS) - { - LLSD args; - args["MAX_BANNED"] = llformat("%d",ESTATE_MAX_ACCESS_IDS); - LLNotificationsUtil::add("MaxBannedAgentsOnRegion", args); - return; - } - accessAddCore(ESTATE_ACCESS_BANNED_AGENT_ADD, "EstateBannedAgentAdd"); -} - -void LLPanelEstateInfo::onClickRemoveBannedAgent() -{ - accessRemoveCore(ESTATE_ACCESS_BANNED_AGENT_REMOVE, "EstateBannedAgentRemove", "banned_avatar_name_list"); -} - -// static -void LLPanelEstateInfo::onClickAddEstateManager() -{ - LLCtrlListInterface *list = childGetListInterface("estate_manager_name_list"); - if (!list) return; - if (gHippoGridManager->getConnectedGrid()->isSecondLife() && list->getItemCount() >= ESTATE_MAX_MANAGERS) - { // Tell user they can't add more managers - LLSD args; - args["MAX_MANAGER"] = llformat("%d",ESTATE_MAX_MANAGERS); - LLNotificationsUtil::add("MaxManagersOnRegion", args); - } - else - { // Go pick managers to add - accessAddCore(ESTATE_ACCESS_MANAGER_ADD, "EstateManagerAdd"); - } -} - -// static -void LLPanelEstateInfo::onClickRemoveEstateManager() -{ - accessRemoveCore(ESTATE_ACCESS_MANAGER_REMOVE, "EstateManagerRemove", "estate_manager_name_list"); -} - //--------------------------------------------------------------------------- // Kick from estate methods //--------------------------------------------------------------------------- @@ -1734,11 +1658,13 @@ struct LLEstateAccessChangeInfo LLSD sd; sd["name"] = mDialogName; sd["operation"] = (S32)mOperationFlag; - for (uuid_vec_t::const_iterator it = mAgentOrGroupIDs.begin(); - it != mAgentOrGroupIDs.end(); - ++it) + for (U32 i = 0; i < mAgentOrGroupIDs.size(); ++i) { - sd["allowed_ids"].append(*it); + sd["allowed_ids"].append(mAgentOrGroupIDs[i]); + if (mAgentNames.size() > i) + { + sd["allowed_names"].append(mAgentNames[i].asLLSD()); + } } return sd; } @@ -1746,316 +1672,9 @@ struct LLEstateAccessChangeInfo U32 mOperationFlag; // ESTATE_ACCESS_BANNED_AGENT_ADD, _REMOVE, etc. std::string mDialogName; uuid_vec_t mAgentOrGroupIDs; // List of agent IDs to apply to this change + std::vector mAgentNames; // Optional list of the agent names for notifications }; -// Special case callback for groups, since it has different callback format than names -void LLPanelEstateInfo::addAllowedGroup2(LLUUID id) -{ - LLSD payload; - payload["operation"] = (S32)ESTATE_ACCESS_ALLOWED_GROUP_ADD; - payload["dialog_name"] = "EstateAllowedGroupAdd"; - payload["allowed_ids"].append(id); - - LLSD args; - args["ALL_ESTATES"] = all_estates_text(); - - LLNotification::Params params("EstateAllowedGroupAdd"); - params.payload(payload) - .substitutions(args) - .functor(accessCoreConfirm); - if (isLindenEstate()) - { - LLNotifications::instance().forceResponse(params, 0); - } - else - { - LLNotifications::instance().add(params); - } -} - -// static -void LLPanelEstateInfo::accessAddCore(U32 operation_flag, const std::string& dialog_name) -{ - LLSD payload; - payload["operation"] = (S32)operation_flag; - payload["dialog_name"] = dialog_name; - // agent id filled in after avatar picker - - LLNotification::Params params("ChangeLindenAccess"); - params.payload(payload) - .functor(accessAddCore2); - - if (isLindenEstate()) - { - LLNotifications::instance().add(params); - } - else - { - // same as clicking "OK" - LLNotifications::instance().forceResponse(params, 0); - } -} - -// static -bool LLPanelEstateInfo::accessAddCore2(const LLSD& notification, const LLSD& response) -{ - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - if (option != 0) - { - // abort change - return false; - } - - LLEstateAccessChangeInfo* change_info = new LLEstateAccessChangeInfo(notification["payload"]); - // avatar picker yes multi-select, yes close-on-select - LLFloaterAvatarPicker::show(boost::bind(&LLPanelEstateInfo::accessAddCore3, _1, change_info), TRUE, TRUE); - return false; -} - -// static -void LLPanelEstateInfo::accessAddCore3(const uuid_vec_t& ids, LLEstateAccessChangeInfo* change_info) -{ - if (!change_info) return; - if (ids.empty()) - { - // User didn't select a name. - delete change_info; - change_info = NULL; - return; - } - // User did select a name. - change_info->mAgentOrGroupIDs = ids; - // Can't put estate owner on ban list - LLPanelEstateInfo* panel = LLFloaterRegionInfo::getPanelEstate(); - if (!panel) return; - LLViewerRegion* region = gAgent.getRegion(); - if (!region) return; - - if (change_info->mOperationFlag & ESTATE_ACCESS_ALLOWED_AGENT_ADD) - { - LLCtrlListInterface *list = panel->childGetListInterface("allowed_avatar_name_list"); - int currentCount = (list ? list->getItemCount() : 0); - if (ids.size() + currentCount > ESTATE_MAX_ACCESS_IDS) - { - LLSD args; - args["NUM_ADDED"] = llformat("%d",ids.size()); - args["MAX_AGENTS"] = llformat("%d",ESTATE_MAX_ACCESS_IDS); - args["LIST_TYPE"] = LLTrans::getString("RegionInfoListTypeAllowedAgents"); - args["NUM_EXCESS"] = llformat("%d",(ids.size()+currentCount)-ESTATE_MAX_ACCESS_IDS); - LLNotificationsUtil::add("MaxAgentOnRegionBatch", args); - delete change_info; - return; - } - } - if (change_info->mOperationFlag & ESTATE_ACCESS_BANNED_AGENT_ADD) - { - LLCtrlListInterface *list = panel->childGetListInterface("banned_avatar_name_list"); - int currentCount = (list ? list->getItemCount() : 0); - if (ids.size() + currentCount > ESTATE_MAX_ACCESS_IDS) - { - LLSD args; - args["NUM_ADDED"] = llformat("%d",ids.size()); - args["MAX_AGENTS"] = llformat("%d",ESTATE_MAX_ACCESS_IDS); - args["LIST_TYPE"] = LLTrans::getString("RegionInfoListTypeBannedAgents"); - args["NUM_EXCESS"] = llformat("%d",(ids.size()+currentCount)-ESTATE_MAX_ACCESS_IDS); - LLNotificationsUtil::add("MaxAgentOnRegionBatch", args); - delete change_info; - return; - } - } - - LLSD args; - args["ALL_ESTATES"] = all_estates_text(); - - LLNotification::Params params(change_info->mDialogName); - params.substitutions(args) - .payload(change_info->asLLSD()) - .functor(accessCoreConfirm); - - if (isLindenEstate()) - { - // just apply to this estate - LLNotifications::instance().forceResponse(params, 0); - } - else - { - // ask if this estate or all estates with this owner - LLNotifications::instance().add(params); - } -} - -// static -void LLPanelEstateInfo::accessRemoveCore(U32 operation_flag, const std::string& dialog_name, const std::string& list_ctrl_name) -{ - LLPanelEstateInfo* panel = LLFloaterRegionInfo::getPanelEstate(); - if (!panel) return; - LLNameListCtrl* name_list = panel->getChild(list_ctrl_name); - if (!name_list) return; - - std::vector list_vector = name_list->getAllSelected(); - if (list_vector.size() == 0) - return; - - LLSD payload; - payload["operation"] = (S32)operation_flag; - payload["dialog_name"] = dialog_name; - - for (std::vector::const_iterator iter = list_vector.begin(); - iter != list_vector.end(); - iter++) - { - LLScrollListItem *item = (*iter); - payload["allowed_ids"].append(item->getUUID()); - } - - LLNotification::Params params("ChangeLindenAccess"); - params.payload(payload) - .functor(accessRemoveCore2); - - if (isLindenEstate()) - { - // warn on change linden estate - LLNotifications::instance().add(params); - } - else - { - // just proceed, as if clicking OK - LLNotifications::instance().forceResponse(params, 0); - } -} - -// static -bool LLPanelEstateInfo::accessRemoveCore2(const LLSD& notification, const LLSD& response) -{ - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - if (option != 0) - { - // abort - return false; - } - - // If Linden estate, can only apply to "this" estate, not all estates - // owned by NULL. - if (isLindenEstate()) - { - accessCoreConfirm(notification, response); - } - else - { - LLSD args; - args["ALL_ESTATES"] = all_estates_text(); - LLNotificationsUtil::add(notification["payload"]["dialog_name"], - args, - notification["payload"], - accessCoreConfirm); - } - return false; -} - -// Used for both access add and remove operations, depending on the mOperationFlag -// passed in (ESTATE_ACCESS_BANNED_AGENT_ADD, ESTATE_ACCESS_ALLOWED_AGENT_REMOVE, etc.) -// static -bool LLPanelEstateInfo::accessCoreConfirm(const LLSD& notification, const LLSD& response) -{ - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - const U32 originalFlags = (U32)notification["payload"]["operation"].asInteger(); - - LLViewerRegion* region = gAgent.getRegion(); - - LLSD::array_const_iterator end_it = notification["payload"]["allowed_ids"].endArray(); - - for (LLSD::array_const_iterator iter = notification["payload"]["allowed_ids"].beginArray(); - iter != end_it; - iter++) - { - U32 flags = originalFlags; - if (iter + 1 != end_it) - flags |= ESTATE_ACCESS_NO_REPLY; - - const LLUUID id = iter->asUUID(); - if (((U32)notification["payload"]["operation"].asInteger() & ESTATE_ACCESS_BANNED_AGENT_ADD) - && region && (region->getOwner() == id)) - { - LLNotificationsUtil::add("OwnerCanNotBeDenied"); - break; - } - switch(option) - { - case 0: - // This estate - sendEstateAccessDelta(flags, id); - break; - case 1: - { - // All estates, either than I own or manage for this owner. - // This will be verified on simulator. JC - if (!region) break; - if (region->getOwner() == gAgent.getID() - || gAgent.isGodlike()) - { - flags |= ESTATE_ACCESS_APPLY_TO_ALL_ESTATES; - sendEstateAccessDelta(flags, id); - } - else if (region->isEstateManager()) - { - flags |= ESTATE_ACCESS_APPLY_TO_MANAGED_ESTATES; - sendEstateAccessDelta(flags, id); - } - break; - } - case 2: - default: - break; - } - } - return false; -} - -// key = "estateaccessdelta" -// str(estate_id) will be added to front of list by forward_EstateOwnerRequest_to_dataserver -// str[0] = str(agent_id) requesting the change -// str[1] = str(flags) (ESTATE_ACCESS_DELTA_*) -// str[2] = str(agent_id) to add or remove -// static -void LLPanelEstateInfo::sendEstateAccessDelta(U32 flags, const LLUUID& agent_or_group_id) -{ - LLMessageSystem* msg = gMessageSystem; - msg->newMessage("EstateOwnerMessage"); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null); //not used - - msg->nextBlock("MethodData"); - msg->addString("Method", "estateaccessdelta"); - msg->addUUID("Invoice", LLFloaterRegionInfo::getLastInvoice()); - - std::string buf; - gAgent.getID().toString(buf); - msg->nextBlock("ParamList"); - msg->addString("Parameter", buf); - - buf = llformat("%u", flags); - msg->nextBlock("ParamList"); - msg->addString("Parameter", buf); - - agent_or_group_id.toString(buf); - msg->nextBlock("ParamList"); - msg->addString("Parameter", buf); - - - LLPanelEstateInfo* panel = LLFloaterRegionInfo::getPanelEstate(); - - if (flags & (ESTATE_ACCESS_ALLOWED_AGENT_ADD | ESTATE_ACCESS_ALLOWED_AGENT_REMOVE | - ESTATE_ACCESS_BANNED_AGENT_ADD | ESTATE_ACCESS_BANNED_AGENT_REMOVE)) - { - - panel->clearAccessLists(); - } - - gAgent.sendReliableMessage(); -} - // static void LLPanelEstateInfo::updateEstateOwnerName(const std::string& name) { @@ -2083,36 +1702,9 @@ void LLPanelEstateInfo::updateControls(LLViewerRegion* region) BOOL manager = (region && region->isEstateManager()); setCtrlsEnabled(god || owner || manager); - BOOL has_allowed_avatar = getChild("allowed_avatar_name_list")->getFirstSelected() ? TRUE : FALSE; - BOOL has_allowed_group = getChild("allowed_group_name_list")->getFirstSelected() ? TRUE : FALSE; - BOOL has_banned_agent = getChild("banned_avatar_name_list")->getFirstSelected() ? TRUE : FALSE; - BOOL has_estate_manager = getChild("estate_manager_name_list")->getFirstSelected() ? TRUE : FALSE; - - getChildView("add_allowed_avatar_btn")->setEnabled(god || owner || manager); - getChildView("remove_allowed_avatar_btn")->setEnabled(has_allowed_avatar && (god || owner || manager)); - getChildView("allowed_avatar_name_list")->setEnabled(god || owner || manager); - - getChildView("add_allowed_group_btn")->setEnabled(god || owner || manager); - getChildView("remove_allowed_group_btn")->setEnabled(has_allowed_group && (god || owner || manager) ); - getChildView("allowed_group_name_list")->setEnabled(god || owner || manager); - - // Can't ban people from mainland, orientation islands, etc. because this - // creates much network traffic and server load. - // Disable their accounts in CSR tool instead. - bool linden_estate = isLindenEstate(); - bool enable_ban = (god || owner || manager) && !linden_estate; - getChildView("add_banned_avatar_btn")->setEnabled(enable_ban); - getChildView("remove_banned_avatar_btn")->setEnabled(has_banned_agent && enable_ban); - getChildView("banned_avatar_name_list")->setEnabled(god || owner || manager); - getChildView("message_estate_btn")->setEnabled(god || owner || manager); getChildView("kick_user_from_estate_btn")->setEnabled(god || owner || manager); - // estate managers can't add estate managers - getChildView("add_estate_manager_btn")->setEnabled(god || owner); - getChildView("remove_estate_manager_btn")->setEnabled(has_estate_manager && (god || owner)); - getChildView("estate_manager_name_list")->setEnabled(god || owner); - refresh(); } @@ -2134,10 +1726,6 @@ bool LLPanelEstateInfo::refreshFromRegion(LLViewerRegion* region) //integers.push_back(LLFloaterRegionInfo::());::getPanelEstate(); - LLPanelEstateInfo* panel = LLFloaterRegionInfo::getPanelEstate(); - panel->clearAccessLists(); - - sendEstateOwnerMessage(gMessageSystem, "getinfo", invoice, strings); refresh(); @@ -2169,14 +1757,10 @@ BOOL LLPanelEstateInfo::postBuild() initCtrl("limit_payment"); initCtrl("limit_age_verified"); initCtrl("voice_chat_check"); - initHelpBtn("estate_manager_help", "HelpEstateEstateManager"); initHelpBtn("use_global_time_help", "HelpEstateUseGlobalTime"); initHelpBtn("fixed_sun_help", "HelpEstateFixedSun"); initHelpBtn("externally_visible_help", "HelpEstateExternallyVisible"); initHelpBtn("allow_direct_teleport_help", "HelpEstateAllowDirectTeleport"); - initHelpBtn("allow_resident_help", "HelpEstateAllowResident"); - initHelpBtn("allow_group_help", "HelpEstateAllowGroup"); - initHelpBtn("ban_resident_help", "HelpEstateBanResident"); initHelpBtn("voice_chat_help", "HelpEstateVoiceChat"); // Set up the Legacy Estate Environment checkboxes @@ -2188,49 +1772,6 @@ BOOL LLPanelEstateInfo::postBuild() fixed_sun->setCommitCallback(boost::bind(on_change_fixed_sun, _2, global_time, hour_slider)); } - getChild("allowed_avatar_name_list")->setCommitCallback(boost::bind(&LLPanelEstateInfo::onChangeChildCtrl, this, _1)); - LLNameListCtrl *avatar_name_list = getChild("allowed_avatar_name_list"); - if (avatar_name_list) - { - avatar_name_list->setCommitOnSelectionChange(TRUE); - avatar_name_list->setMaxItemCount(ESTATE_MAX_ACCESS_IDS); - } - - childSetAction("add_allowed_avatar_btn", boost::bind(&LLPanelEstateInfo::onClickAddAllowedAgent, this)); - childSetAction("remove_allowed_avatar_btn", boost::bind(&LLPanelEstateInfo::onClickRemoveAllowedAgent, this)); - - getChild("allowed_group_name_list")->setCommitCallback(boost::bind(&LLPanelEstateInfo::onChangeChildCtrl, this, _1)); - LLNameListCtrl* group_name_list = getChild("allowed_group_name_list"); - if (group_name_list) - { - group_name_list->setCommitOnSelectionChange(TRUE); - group_name_list->setMaxItemCount(ESTATE_MAX_ACCESS_IDS); - } - - getChild("add_allowed_group_btn")->setCommitCallback(boost::bind(&LLPanelEstateInfo::onClickAddAllowedGroup, this)); - childSetAction("remove_allowed_group_btn", boost::bind(&LLPanelEstateInfo::onClickRemoveAllowedGroup, this)); - - getChild("banned_avatar_name_list")->setCommitCallback(boost::bind(&LLPanelEstateInfo::onChangeChildCtrl, this, _1)); - LLNameListCtrl* banned_name_list = getChild("banned_avatar_name_list"); - if (banned_name_list) - { - banned_name_list->setCommitOnSelectionChange(TRUE); - banned_name_list->setMaxItemCount(ESTATE_MAX_ACCESS_IDS); - } - - childSetAction("add_banned_avatar_btn", boost::bind(&LLPanelEstateInfo::onClickAddBannedAgent, this)); - childSetAction("remove_banned_avatar_btn", boost::bind(&LLPanelEstateInfo::onClickRemoveBannedAgent, this)); - - getChild("estate_manager_name_list")->setCommitCallback(boost::bind(&LLPanelEstateInfo::onChangeChildCtrl, this, _1)); - LLNameListCtrl* manager_name_list = getChild("estate_manager_name_list"); - if (manager_name_list) - { - manager_name_list->setCommitOnSelectionChange(TRUE); - manager_name_list->setMaxItemCount(ESTATE_MAX_MANAGERS * 4); // Allow extras for dupe issue - } - - childSetAction("add_estate_manager_btn", boost::bind(&LLPanelEstateInfo::onClickAddEstateManager, this)); - childSetAction("remove_estate_manager_btn", boost::bind(&LLPanelEstateInfo::onClickRemoveEstateManager, this)); childSetAction("message_estate_btn", boost::bind(&LLPanelEstateInfo::onClickMessageEstate, this)); childSetAction("kick_user_from_estate_btn", boost::bind(&LLPanelEstateInfo::onClickKickUser, this)); @@ -2381,39 +1922,6 @@ void LLPanelEstateInfo::getEstateOwner() } */ -class LLEstateChangeInfoResponder : public LLHTTPClient::ResponderWithResult -{ - LOG_CLASS(LLEstateChangeInfoResponder); -public: - LLEstateChangeInfoResponder(LLPanelEstateInfo* panel) - { - mpPanel = panel->getHandle(); - } - -protected: - // if we get a normal response, handle it here - virtual void httpSuccess() - { - LL_INFOS("Windlight") << "Successfully committed estate info" << LL_ENDL; - - // refresh the panel from the database - LLPanelEstateInfo* panel = dynamic_cast(mpPanel.get()); - if (panel) - panel->refresh(); - } - - // if we get an error response - virtual void httpFailure() - { - LL_WARNS("Windlight") << dumpResponse() << LL_ENDL; - } - - /*virtual*/ char const* getName(void) const { return "LLEstateChangeInfoResponder"; } - -private: - LLHandle mpPanel; -}; - const std::string LLPanelEstateInfo::getOwnerName() const { return getChild("estate_owner")->getValue().asString(); @@ -2424,22 +1932,6 @@ void LLPanelEstateInfo::setOwnerName(const std::string& name) getChild("estate_owner")->setValue(LLSD(name)); } -void LLPanelEstateInfo::clearAccessLists() -{ - LLNameListCtrl* name_list = getChild("allowed_avatar_name_list"); - if (name_list) - { - name_list->deleteAllItems(); - } - - name_list = getChild("banned_avatar_name_list"); - if (name_list) - { - name_list->deleteAllItems(); - } - updateControls(gAgent.getRegion()); -} - // static void LLPanelEstateInfo::onClickMessageEstate(void* userdata) { @@ -2853,25 +2345,13 @@ bool LLDispatchEstateUpdateInfo::operator()( return true; } - -// key = "setaccess" -// strings[0] = str(estate_id) -// strings[1] = str(packed_access_lists) -// strings[2] = str(num allowed agent ids) -// strings[3] = str(num allowed group ids) -// strings[4] = str(num banned agent ids) -// strings[5] = str(num estate manager agent ids) -// strings[6] = bin(uuid) -// strings[7] = bin(uuid) -// strings[8] = bin(uuid) -// ... bool LLDispatchSetEstateAccess::operator()( const LLDispatcher* dispatcher, const std::string& key, const LLUUID& invoice, const sparam_t& strings) { - LLPanelEstateInfo* panel = LLFloaterRegionInfo::getPanelEstate(); + LLPanelEstateAccess* panel = LLFloaterRegionInfo::getPanelAccess(); if (!panel) return true; S32 index = 1; // skip estate_id @@ -2903,132 +2383,79 @@ bool LLDispatchSetEstateAccess::operator()( LL_WARNS() << "non-zero count for managers, but no corresponding flag" << LL_ENDL; } + // Build an LLSD to fake the http response on older grids + LLSD result; + // grab the UUID's out of the string fields if (access_flags & ESTATE_ACCESS_ALLOWED_AGENTS) { - LLNameListCtrl* allowed_agent_name_list; - allowed_agent_name_list = panel->getChild("allowed_avatar_name_list"); - - int totalAllowedAgents = num_allowed_agents; - - if (allowed_agent_name_list) - { - totalAllowedAgents += allowed_agent_name_list->getItemCount(); - } - - LLStringUtil::format_map_t args; - args["[ALLOWEDAGENTS]"] = llformat ("%d", totalAllowedAgents); - args["[MAXACCESS]"] = llformat ("%d", ESTATE_MAX_ACCESS_IDS); - std::string msg = LLTrans::getString("RegionInfoAllowedResidents", args); - panel->getChild("allow_resident_label")->setValue(LLSD(msg)); + LLNameListCtrl* allowed_agent_name_list = panel->getChild("allowed_avatar_name_list"); if (allowed_agent_name_list) { - // Don't sort these as we add them, sort them when we are done. - allowed_agent_name_list->clearSortOrder(); - for (S32 i = 0; i < num_allowed_agents && i < ESTATE_MAX_ACCESS_IDS; i++) + auto& allowed_agents = result["AllowedAgents"]; + for (const auto& id : allowed_agent_name_list->getAllIDs()) + { + allowed_agents.append(LLSD().with("id", id)); + } + for (S32 i = 0; i < num_allowed_agents; ++i) { LLUUID id; memcpy(id.mData, strings[index++].data(), UUID_BYTES); /* Flawfinder: ignore */ - allowed_agent_name_list->addNameItem(id); + allowed_agents.append(LLSD().with("id", id)); } - allowed_agent_name_list->sortByName(TRUE); } } if (access_flags & ESTATE_ACCESS_ALLOWED_GROUPS) { - LLNameListCtrl* allowed_group_name_list; - allowed_group_name_list = panel->getChild("allowed_group_name_list"); - - LLStringUtil::format_map_t args; - args["[ALLOWEDGROUPS]"] = llformat ("%d", num_allowed_groups); - args["[MAXACCESS]"] = llformat ("%d", ESTATE_MAX_GROUP_IDS); - std::string msg = LLTrans::getString("RegionInfoAllowedGroups", args); - panel->getChild("allow_group_label")->setValue(LLSD(msg)); - - if (allowed_group_name_list) + auto& allowed_groups = result["AllowedGroups"]; + for (S32 i = 0; i < num_allowed_groups; ++i) { - // Don't sort these as we add them, sort them when we are done. - allowed_group_name_list->clearSortOrder(); - allowed_group_name_list->deleteAllItems(); - for (S32 i = 0; i < num_allowed_groups && i < ESTATE_MAX_GROUP_IDS; i++) - { - LLUUID id; - memcpy(id.mData, strings[index++].data(), UUID_BYTES); /* Flawfinder: ignore */ - allowed_group_name_list->addGroupNameItem(id); - } - allowed_group_name_list->sortByName(TRUE); + LLUUID id; + memcpy(id.mData, strings[index++].data(), UUID_BYTES); /* Flawfinder: ignore */ + allowed_groups.append(LLSD().with("id", id)); } } if (access_flags & ESTATE_ACCESS_BANNED_AGENTS) { - LLNameListCtrl* banned_agent_name_list; - banned_agent_name_list = panel->getChild("banned_avatar_name_list"); - - int totalBannedAgents = num_banned_agents; - - if (banned_agent_name_list) + if (LLNameListCtrl* banned_agent_name_list = panel->getChild("banned_avatar_name_list")) { - totalBannedAgents += banned_agent_name_list->getItemCount(); - } - - - LLStringUtil::format_map_t args; - args["[BANNEDAGENTS]"] = llformat("%d", totalBannedAgents); - args["[MAXBANNED]"] = llformat("%d", ESTATE_MAX_ACCESS_IDS); - std::string msg = LLTrans::getString("RegionInfoBannedResidents", args); - panel->getChild("ban_resident_label")->setValue(LLSD(msg)); - - if (banned_agent_name_list) - { - // Don't sort these as we add them, sort them when we are done. - banned_agent_name_list->clearSortOrder(); - - for (S32 i = 0; i < num_banned_agents && i < ESTATE_MAX_ACCESS_IDS; i++) + auto& banned_agents = result["BannedAgents"]; + for (const auto& id : banned_agent_name_list->getAllIDs()) + { + banned_agents.append(LLSD().with("id", id)); + } + for (S32 i = 0; i < num_banned_agents; i++) { LLUUID id; memcpy(id.mData, strings[index++].data(), UUID_BYTES); /* Flawfinder: ignore */ - banned_agent_name_list->addNameItem(id); + banned_agents.append(LLSD().with("id", id)); } - banned_agent_name_list->sortByName(TRUE); } } if (access_flags & ESTATE_ACCESS_MANAGERS) { - LLStringUtil::format_map_t args; - args["[ESTATEMANAGERS]"] = llformat("%d", num_estate_managers); - args["[MAXMANAGERS]"] = llformat("%d", ESTATE_MAX_MANAGERS); - std::string msg = LLTrans::getString("RegionInfoEstateManagers", args); - panel->getChild("estate_manager_label")->setValue(LLSD(msg)); - - LLNameListCtrl* estate_manager_name_list = - panel->getChild("estate_manager_name_list"); - if (estate_manager_name_list) - { - // Don't sort these as we add them, sort them when we are done. - estate_manager_name_list->clearSortOrder(); - - estate_manager_name_list->deleteAllItems(); // Clear existing entries - - // There should be only ESTATE_MAX_MANAGERS people in the list, but if the database gets more (SL-46107) don't - // truncate the list unless it's really big. Go ahead and show the extras so the user doesn't get confused, - // and they can still remove them. - for (S32 i = 0; i < num_estate_managers && i < (ESTATE_MAX_MANAGERS * 4); i++) - { - LLUUID id; - memcpy(id.mData, strings[index++].data(), UUID_BYTES); /* Flawfinder: ignore */ - estate_manager_name_list->addNameItem(id); - } - estate_manager_name_list->sortByName(TRUE); + auto& managers = result["Managers"]; + for (S32 i = 0; i < num_estate_managers; ++i) + { + LLUUID id; + memcpy(id.mData, strings[index++].data(), UUID_BYTES); /* Flawfinder: ignore */ + managers.append(LLSD().with("id", id)); } } - // Update the buttons which may change based on the list contents but also needs to account for general access features. - panel->updateControls(gAgent.getRegion()); - + if (panel) + { + panel->onEstateAccessReceived(result); // Until HTTP response use UDP Result + if (panel->getPendingUpdate()) + { + panel->setPendingUpdate(false); + panel->updateLists(); + } + } return true; } @@ -3626,6 +3053,1268 @@ void LLPanelEnvironmentInfo::onRegionSettingsApplied(bool ok) } } +#if 0 // Singu TODO: Experiences +LLPanelRegionExperiences::LLPanelRegionExperiences() +: mTrusted(nullptr) +, mAllowed(nullptr) +, mBlocked(nullptr) +{ + mFactoryMap["panel_trusted"] = LLCallbackMap(create_xp_list_editor, reinterpret_cast(&mTrusted)); + mFactoryMap["panel_allowed"] = LLCallbackMap(create_xp_list_editor, reinterpret_cast(&mAllowed)); + mFactoryMap["panel_blocked"] = LLCallbackMap(create_xp_list_editor, reinterpret_cast(&mBlocked)); + LLUICtrlFactory::getInstance()->buildPanel(this, "panel_region_experiences.xml", &mFactoryMap); +} + +BOOL LLPanelRegionExperiences::postBuild() +{ + setupList(mAllowed, "panel_allowed", ESTATE_EXPERIENCE_ALLOWED_ADD, ESTATE_EXPERIENCE_ALLOWED_REMOVE); + setupList(mTrusted, "panel_trusted", ESTATE_EXPERIENCE_TRUSTED_ADD, ESTATE_EXPERIENCE_TRUSTED_REMOVE); + setupList(mBlocked, "panel_blocked", ESTATE_EXPERIENCE_BLOCKED_ADD, ESTATE_EXPERIENCE_BLOCKED_REMOVE); + + getChild("trusted_layout_panel")->setVisible(TRUE); + getChild("experiences_help_text")->setText(getString("estate_caption")); + getChild("trusted_text_help")->setText(getString("trusted_estate_text")); + getChild("allowed_text_help")->setText(getString("allowed_estate_text")); + getChild("blocked_text_help")->setText(getString("blocked_estate_text")); + + return LLPanelRegionInfo::postBuild(); +} + +void LLPanelRegionExperiences::setupList(LLPanelExperienceListEditor* child, const char* control_name, U32 add_id, U32 remove_id ) +{ + //LLPanelExperienceListEditor* child = findChild(control_name); + if(child) + { + child->getChild("text_name")->setText(child->getString(control_name)); + child->setMaxExperienceIDs(ESTATE_MAX_EXPERIENCE_IDS); + child->setAddedCallback( boost::bind(&LLPanelRegionExperiences::itemChanged, this, add_id, _1)); + child->setRemovedCallback(boost::bind(&LLPanelRegionExperiences::itemChanged, this, remove_id, _1)); + } + + //return child; +} + + +void LLPanelRegionExperiences::processResponse( const LLSD& content ) +{ + if(content.has("default")) + { + mDefaultExperience = content["default"].asUUID(); + } + + mAllowed->setExperienceIds(content["allowed"]); + mBlocked->setExperienceIds(content["blocked"]); + + LLSD trusted = content["trusted"]; + if(mDefaultExperience.notNull()) + { + mTrusted->setStickyFunction(boost::bind(LLPanelExperiencePicker::FilterMatching, _1, mDefaultExperience)); + trusted.append(mDefaultExperience); + } + + mTrusted->setExperienceIds(trusted); + + mAllowed->refreshExperienceCounter(); + mBlocked->refreshExperienceCounter(); + mTrusted->refreshExperienceCounter(); + +} + +// Used for both access add and remove operations, depending on the flag +// passed in (ESTATE_EXPERIENCE_ALLOWED_ADD, ESTATE_EXPERIENCE_ALLOWED_REMOVE, etc.) +// static +bool LLPanelRegionExperiences::experienceCoreConfirm(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + const U32 originalFlags = (U32)notification["payload"]["operation"].asInteger(); + + LLViewerRegion* region = gAgent.getRegion(); + + LLSD::array_const_iterator end_it = notification["payload"]["allowed_ids"].endArray(); + + for (LLSD::array_const_iterator iter = notification["payload"]["allowed_ids"].beginArray(); + iter != end_it; + iter++) + { + U32 flags = originalFlags; + if (iter + 1 != end_it) + flags |= ESTATE_ACCESS_NO_REPLY; + + const LLUUID id = iter->asUUID(); + switch(option) + { + case 0: + // This estate + sendEstateExperienceDelta(flags, id); + break; + case 1: + { + // All estates, either than I own or manage for this owner. + // This will be verified on simulator. JC + if (!region) break; + if (region->getOwner() == gAgent.getID() + || gAgent.isGodlike()) + { + flags |= ESTATE_ACCESS_APPLY_TO_ALL_ESTATES; + sendEstateExperienceDelta(flags, id); + } + else if (region->isEstateManager()) + { + flags |= ESTATE_ACCESS_APPLY_TO_MANAGED_ESTATES; + sendEstateExperienceDelta(flags, id); + } + break; + } + case 2: + default: + break; + } + } + return false; +} + + +// Send the actual "estateexperiencedelta" message +void LLPanelRegionExperiences::sendEstateExperienceDelta(U32 flags, const LLUUID& experience_id) +{ + strings_t str(3, std::string()); + gAgent.getID().toString(str[0]); + str[1] = llformat("%u", flags); + experience_id.toString(str[2]); + + LLPanelRegionExperiences* panel = LLFloaterRegionInfo::getPanelExperiences(); + if (panel) + { + panel->sendEstateOwnerMessage(gMessageSystem, "estateexperiencedelta", LLFloaterRegionInfo::getLastInvoice(), str); + } +} + + +void LLPanelRegionExperiences::infoCallback(LLHandle handle, const LLSD& content) +{ + if (handle.isDead()) + return; + + LLPanelRegionExperiences* floater = handle.get(); + if (floater) + { + floater->processResponse(content); + } +} + +/*static*/ +std::string LLPanelRegionExperiences::regionCapabilityQuery(LLViewerRegion* region, const std::string &cap) +{ + // region->getHandle() How to get a region * from a handle? + + return region->getCapability(cap); +} + +bool LLPanelRegionExperiences::refreshFromRegion(LLViewerRegion* region) +{ + BOOL allow_modify = gAgent.isGodlike() || (region && region->canManageEstate()); + + mAllowed->loading(); + mAllowed->setReadonly(!allow_modify); + // remove grid-wide experiences + mAllowed->addFilter(boost::bind(LLPanelExperiencePicker::FilterWithProperty, _1, LLExperienceCache::PROPERTY_GRID)); + // remove default experience + mAllowed->addFilter(boost::bind(LLPanelExperiencePicker::FilterMatching, _1, mDefaultExperience)); + + mBlocked->loading(); + mBlocked->setReadonly(!allow_modify); + // only grid-wide experiences + mBlocked->addFilter(boost::bind(LLPanelExperiencePicker::FilterWithoutProperty, _1, LLExperienceCache::PROPERTY_GRID)); + // but not privileged ones + mBlocked->addFilter(boost::bind(LLPanelExperiencePicker::FilterWithProperty, _1, LLExperienceCache::PROPERTY_PRIVILEGED)); + // remove default experience + mBlocked->addFilter(boost::bind(LLPanelExperiencePicker::FilterMatching, _1, mDefaultExperience)); + + mTrusted->loading(); + mTrusted->setReadonly(!allow_modify); + + LLExperienceCache::instance().getRegionExperiences(boost::bind(&LLPanelRegionExperiences::regionCapabilityQuery, region, _1), + boost::bind(&LLPanelRegionExperiences::infoCallback, getDerivedHandle(), _1)); + + return LLPanelRegionInfo::refreshFromRegion(region); +} + +LLSD LLPanelRegionExperiences::addIds(LLPanelExperienceListEditor* panel) +{ + LLSD ids; + const uuid_list_t& id_list = panel->getExperienceIds(); + for(uuid_list_t::const_iterator it = id_list.begin(); it != id_list.end(); ++it) + { + ids.append(*it); + } + return ids; +} + + +BOOL LLPanelRegionExperiences::sendUpdate() +{ + LLViewerRegion* region = gAgent.getRegion(); + + LLSD content; + + content["allowed"]=addIds(mAllowed); + content["blocked"]=addIds(mBlocked); + content["trusted"]=addIds(mTrusted); + + LLExperienceCache::instance().setRegionExperiences(boost::bind(&LLPanelRegionExperiences::regionCapabilityQuery, region, _1), + content, boost::bind(&LLPanelRegionExperiences::infoCallback, getDerivedHandle(), _1)); + + return TRUE; +} + +void LLPanelRegionExperiences::itemChanged( U32 event_type, const LLUUID& id ) +{ + std::string dialog_name; + switch (event_type) + { + case ESTATE_EXPERIENCE_ALLOWED_ADD: + dialog_name = "EstateAllowedExperienceAdd"; + break; + + case ESTATE_EXPERIENCE_ALLOWED_REMOVE: + dialog_name = "EstateAllowedExperienceRemove"; + break; + + case ESTATE_EXPERIENCE_TRUSTED_ADD: + dialog_name = "EstateTrustedExperienceAdd"; + break; + + case ESTATE_EXPERIENCE_TRUSTED_REMOVE: + dialog_name = "EstateTrustedExperienceRemove"; + break; + + case ESTATE_EXPERIENCE_BLOCKED_ADD: + dialog_name = "EstateBlockedExperienceAdd"; + break; + + case ESTATE_EXPERIENCE_BLOCKED_REMOVE: + dialog_name = "EstateBlockedExperienceRemove"; + break; + + default: + return; + } + + LLSD payload; + payload["operation"] = (S32)event_type; + payload["dialog_name"] = dialog_name; + payload["allowed_ids"].append(id); + + LLSD args; + args["ALL_ESTATES"] = all_estates_text(); + + LLNotification::Params params(dialog_name); + params.payload(payload) + .substitutions(args) + .functor(LLPanelRegionExperiences::experienceCoreConfirm); + if (LLPanelEstateInfo::isLindenEstate()) + { + LLNotifications::instance().forceResponse(params, 0); + } + else + { + LLNotifications::instance().add(params); + } + + onChangeAnything(); +} + +#endif // Singu TODO: Experiences + +LLPanelEstateAccess::LLPanelEstateAccess() +: LLPanelRegionInfo(), mPendingUpdate(false) +{} + +BOOL LLPanelEstateAccess::postBuild() +{ + // set up the callbacks for the generic controls + initHelpBtn("estate_manager_help", "HelpEstateEstateManager"); + initHelpBtn("allow_resident_help", "HelpEstateAllowResident"); + initHelpBtn("allow_group_help", "HelpEstateAllowGroup"); + initHelpBtn("ban_resident_help", "HelpEstateBanResident"); + + getChild("allowed_avatar_name_list")->setCommitCallback(boost::bind(&LLPanelEstateInfo::onChangeChildCtrl, this, _1)); + LLNameListCtrl *avatar_name_list = getChild("allowed_avatar_name_list"); + if (avatar_name_list) + { + avatar_name_list->setCommitOnSelectionChange(TRUE); + avatar_name_list->setMaxItemCount(ESTATE_MAX_ACCESS_IDS); + } + + getChild("allowed_search_input")->setCommitCallback(boost::bind(&LLPanelEstateAccess::onAllowedSearchEdit, this, _2)); + childSetAction("add_allowed_avatar_btn", boost::bind(&LLPanelEstateAccess::onClickAddAllowedAgent, this)); + childSetAction("remove_allowed_avatar_btn", boost::bind(&LLPanelEstateAccess::onClickRemoveAllowedAgent, this)); + childSetAction("copy_allowed_list_btn", boost::bind(&LLPanelEstateAccess::onClickCopyAllowedList, this)); + + getChild("allowed_group_name_list")->setCommitCallback(boost::bind(&LLPanelEstateInfo::onChangeChildCtrl, this, _1)); + LLNameListCtrl* group_name_list = getChild("allowed_group_name_list"); + if (group_name_list) + { + group_name_list->setCommitOnSelectionChange(TRUE); + group_name_list->setMaxItemCount(ESTATE_MAX_ACCESS_IDS); + } + + getChild("allowed_group_search_input")->setCommitCallback(boost::bind(&LLPanelEstateAccess::onAllowedGroupsSearchEdit, this, _2)); + getChild("add_allowed_group_btn")->setCommitCallback(boost::bind(&LLPanelEstateAccess::onClickAddAllowedGroup, this)); + childSetAction("remove_allowed_group_btn", boost::bind(&LLPanelEstateAccess::onClickRemoveAllowedGroup, this)); + childSetAction("copy_allowed_group_list_btn", boost::bind(&LLPanelEstateAccess::onClickCopyAllowedGroupList, this)); + + getChild("banned_avatar_name_list")->setCommitCallback(boost::bind(&LLPanelEstateAccess::updateChild, this, _1)); + LLNameListCtrl* banned_name_list = getChild("banned_avatar_name_list"); + if (banned_name_list) + { + banned_name_list->setCommitOnSelectionChange(TRUE); + banned_name_list->setMaxItemCount(ESTATE_MAX_ACCESS_IDS); + } + + getChild("banned_search_input")->setCommitCallback(boost::bind(&LLPanelEstateAccess::onBannedSearchEdit, this, _2)); + childSetAction("add_banned_avatar_btn", boost::bind(&LLPanelEstateAccess::onClickAddBannedAgent, this)); + childSetAction("remove_banned_avatar_btn", boost::bind(&LLPanelEstateAccess::onClickRemoveBannedAgent, this)); + childSetAction("copy_banned_list_btn", boost::bind(&LLPanelEstateAccess::onClickCopyBannedList, this)); + + getChild("estate_manager_name_list")->setCommitCallback(boost::bind(&LLPanelEstateAccess::updateChild, this, _1)); + LLNameListCtrl* manager_name_list = getChild("estate_manager_name_list"); + if (manager_name_list) + { + manager_name_list->setCommitOnSelectionChange(TRUE); + manager_name_list->setMaxItemCount(ESTATE_MAX_MANAGERS * 4); // Allow extras for dupe issue + } + + childSetAction("add_estate_manager_btn", boost::bind(&LLPanelEstateAccess::onClickAddEstateManager, this)); + childSetAction("remove_estate_manager_btn", boost::bind(&LLPanelEstateAccess::onClickRemoveEstateManager, this)); + + return TRUE; +} + +void LLPanelEstateAccess::updateControls(LLViewerRegion* region) +{ + BOOL god = gAgent.isGodlike(); + BOOL owner = (region && (region->getOwner() == gAgent.getID())); + BOOL manager = (region && region->isEstateManager()); + bool enable_cotrols = god || owner || manager; + setCtrlsEnabled(enable_cotrols); + + BOOL has_allowed_avatar = getChild("allowed_avatar_name_list")->getFirstSelected() ? TRUE : FALSE; + BOOL has_allowed_group = getChild("allowed_group_name_list")->getFirstSelected() ? TRUE : FALSE; + BOOL has_banned_agent = getChild("banned_avatar_name_list")->getFirstSelected() ? TRUE : FALSE; + BOOL has_estate_manager = getChild("estate_manager_name_list")->getFirstSelected() ? TRUE : FALSE; + + getChildView("add_allowed_avatar_btn")->setEnabled(enable_cotrols); + getChildView("remove_allowed_avatar_btn")->setEnabled(has_allowed_avatar && enable_cotrols); + getChildView("allowed_avatar_name_list")->setEnabled(enable_cotrols); + + getChildView("add_allowed_group_btn")->setEnabled(enable_cotrols); + getChildView("remove_allowed_group_btn")->setEnabled(has_allowed_group && enable_cotrols); + getChildView("allowed_group_name_list")->setEnabled(enable_cotrols); + + // Can't ban people from mainland, orientation islands, etc. because this + // creates much network traffic and server load. + // Disable their accounts in CSR tool instead. + bool linden_estate = LLPanelEstateInfo::isLindenEstate(); + bool enable_ban = enable_cotrols && !linden_estate; + getChildView("add_banned_avatar_btn")->setEnabled(enable_ban); + getChildView("remove_banned_avatar_btn")->setEnabled(has_banned_agent && enable_ban); + getChildView("banned_avatar_name_list")->setEnabled(enable_cotrols); + + // estate managers can't add estate managers + getChildView("add_estate_manager_btn")->setEnabled(god || owner); + getChildView("remove_estate_manager_btn")->setEnabled(has_estate_manager && (god || owner)); + getChildView("estate_manager_name_list")->setEnabled(god || owner); + + if (enable_cotrols != mCtrlsEnabled) + { + mCtrlsEnabled = enable_cotrols; + updateLists(); // update the lists on the agent's access level change + } +} + +//--------------------------------------------------------------------------- +// Add/Remove estate access button callbacks +//--------------------------------------------------------------------------- +void LLPanelEstateAccess::onClickAddAllowedAgent() +{ + LLCtrlListInterface *list = childGetListInterface("allowed_avatar_name_list"); + if (!list) return; + if (list->getItemCount() >= ESTATE_MAX_ACCESS_IDS) + { + //args + + LLSD args; + args["MAX_AGENTS"] = llformat("%d",ESTATE_MAX_ACCESS_IDS); + LLNotificationsUtil::add("MaxAllowedAgentOnRegion", args); + return; + } + accessAddCore(ESTATE_ACCESS_ALLOWED_AGENT_ADD, "EstateAllowedAgentAdd"); +} + +void LLPanelEstateAccess::onClickRemoveAllowedAgent() +{ + accessRemoveCore(ESTATE_ACCESS_ALLOWED_AGENT_REMOVE, "EstateAllowedAgentRemove", "allowed_avatar_name_list"); +} + +void LLPanelEstateAccess::onClickAddAllowedGroup() +{ + LLCtrlListInterface *list = childGetListInterface("allowed_group_name_list"); + if (!list) return; + if (list->getItemCount() >= ESTATE_MAX_ACCESS_IDS) + { + LLSD args; + args["MAX_GROUPS"] = llformat("%d",ESTATE_MAX_ACCESS_IDS); + LLNotificationsUtil::add("MaxAllowedGroupsOnRegion", args); + return; + } + + LLNotification::Params params("ChangeLindenAccess"); + params.functor(boost::bind(&LLPanelEstateAccess::addAllowedGroup, this, _1, _2)); + if (LLPanelEstateInfo::isLindenEstate()) + { + LLNotifications::instance().add(params); + } + else + { + LLNotifications::instance().forceResponse(params, 0); + } +} + +bool LLPanelEstateAccess::addAllowedGroup(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + if (option != 0) return false; + + LLFloater* parent_floater = gFloaterView->getParentFloater(this); + + LLFloaterGroupPicker* widget = LLFloaterGroupPicker::showInstance(LLSD(gAgent.getID())); + if (widget) + { + widget->removeNoneOption(); + widget->setSelectGroupCallback(boost::bind(&LLPanelEstateAccess::addAllowedGroup2, this, _1)); + if (parent_floater) + { + LLRect new_rect = gFloaterView->findNeighboringPosition(parent_floater, widget); + widget->setOrigin(new_rect.mLeft, new_rect.mBottom); + parent_floater->addDependentFloater(widget); + } + } + + return false; +} + +void LLPanelEstateAccess::onClickRemoveAllowedGroup() +{ + accessRemoveCore(ESTATE_ACCESS_ALLOWED_GROUP_REMOVE, "EstateAllowedGroupRemove", "allowed_group_name_list"); +} + +void LLPanelEstateAccess::onClickAddBannedAgent() +{ + LLCtrlListInterface *list = childGetListInterface("banned_avatar_name_list"); + if (!list) return; + if (list->getItemCount() >= ESTATE_MAX_ACCESS_IDS) + { + LLSD args; + args["MAX_BANNED"] = llformat("%d",ESTATE_MAX_ACCESS_IDS); + LLNotificationsUtil::add("MaxBannedAgentsOnRegion", args); + return; + } + accessAddCore(ESTATE_ACCESS_BANNED_AGENT_ADD, "EstateBannedAgentAdd"); +} + +void LLPanelEstateAccess::onClickRemoveBannedAgent() +{ + accessRemoveCore(ESTATE_ACCESS_BANNED_AGENT_REMOVE, "EstateBannedAgentRemove", "banned_avatar_name_list"); +} + +void LLPanelEstateAccess::onClickCopyAllowedList() +{ + copyListToClipboard("allowed_avatar_name_list"); +} + +void LLPanelEstateAccess::onClickCopyAllowedGroupList() +{ + copyListToClipboard("allowed_group_name_list"); +} + +void LLPanelEstateAccess::onClickCopyBannedList() +{ + copyListToClipboard("banned_avatar_name_list"); +} + +// static +void LLPanelEstateAccess::onClickAddEstateManager() +{ + LLCtrlListInterface *list = childGetListInterface("estate_manager_name_list"); + if (!list) return; + if (gHippoGridManager->getConnectedGrid()->isSecondLife() && list->getItemCount() >= ESTATE_MAX_MANAGERS) + { // Tell user they can't add more managers + LLSD args; + args["MAX_MANAGER"] = llformat("%d",ESTATE_MAX_MANAGERS); + LLNotificationsUtil::add("MaxManagersOnRegion", args); + } + else + { // Go pick managers to add + accessAddCore(ESTATE_ACCESS_MANAGER_ADD, "EstateManagerAdd"); + } +} + +// static +void LLPanelEstateAccess::onClickRemoveEstateManager() +{ + accessRemoveCore(ESTATE_ACCESS_MANAGER_REMOVE, "EstateManagerRemove", "estate_manager_name_list"); +} + + +// Special case callback for groups, since it has different callback format than names +void LLPanelEstateAccess::addAllowedGroup2(LLUUID id) +{ + LLPanelEstateAccess* panel = LLFloaterRegionInfo::getPanelAccess(); + if (panel) + { + LLNameListCtrl* group_list = panel->getChild("allowed_group_name_list"); + LLScrollListItem* item = group_list->getNameItemByAgentId(id); + if (item) + { + LLSD args; + args["GROUP"] = item->getColumn(0)->getValue().asString(); + LLNotificationsUtil::add("GroupIsAlreadyInList", args); + return; + } + } + + LLSD payload; + payload["operation"] = (S32)ESTATE_ACCESS_ALLOWED_GROUP_ADD; + payload["dialog_name"] = "EstateAllowedGroupAdd"; + payload["allowed_ids"].append(id); + + LLSD args; + args["ALL_ESTATES"] = all_estates_text(); + + LLNotification::Params params("EstateAllowedGroupAdd"); + params.payload(payload) + .substitutions(args) + .functor(accessCoreConfirm); + if (LLPanelEstateInfo::isLindenEstate()) + { + LLNotifications::instance().forceResponse(params, 0); + } + else + { + LLNotifications::instance().add(params); + } +} + +// static +void LLPanelEstateAccess::accessAddCore(U32 operation_flag, const std::string& dialog_name) +{ + LLSD payload; + payload["operation"] = (S32)operation_flag; + payload["dialog_name"] = dialog_name; + // agent id filled in after avatar picker + + LLNotification::Params params("ChangeLindenAccess"); + params.payload(payload) + .functor(accessAddCore2); + + if (LLPanelEstateInfo::isLindenEstate()) + { + LLNotifications::instance().add(params); + } + else + { + // same as clicking "OK" + LLNotifications::instance().forceResponse(params, 0); + } +} + +// static +bool LLPanelEstateAccess::accessAddCore2(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + if (option != 0) + { + // abort change + return false; + } + + LLEstateAccessChangeInfo* change_info = new LLEstateAccessChangeInfo(notification["payload"]); + LLPanelEstateAccess* panel = LLFloaterRegionInfo::getPanelAccess(); + LLFloater* parent_floater = panel ? gFloaterView->getParentFloater(panel) : NULL; + + // avatar picker yes multi-select, yes close-on-select + LLFloater* child_floater = LLFloaterAvatarPicker::show(boost::bind(&LLPanelEstateAccess::accessAddCore3, _1, _2, change_info), TRUE, TRUE); + + //Allows the closed parent floater to close the child floater (avatar picker) + if (child_floater) + { + parent_floater->addDependentFloater(child_floater); + } + + return false; +} + +// static +void LLPanelEstateAccess::accessAddCore3(const uuid_vec_t& ids, const std::vector& names, LLEstateAccessChangeInfo* change_info) +{ + if (!change_info) return; + if (ids.empty()) + { + // User didn't select a name. + delete change_info; + change_info = NULL; + return; + } + // User did select a name. + change_info->mAgentOrGroupIDs = ids; + // Can't put estate owner on ban list + LLPanelEstateAccess* panel = LLFloaterRegionInfo::getPanelAccess(); + if (!panel) return; + LLViewerRegion* region = gAgent.getRegion(); + if (!region) return; + + if (change_info->mOperationFlag & ESTATE_ACCESS_ALLOWED_AGENT_ADD) + { + LLNameListCtrl* name_list = panel->getChild("allowed_avatar_name_list"); + int currentCount = (name_list ? name_list->getItemCount() : 0); + if (ids.size() + currentCount > ESTATE_MAX_ACCESS_IDS) + { + LLSD args; + args["NUM_ADDED"] = llformat("%d",ids.size()); + args["MAX_AGENTS"] = llformat("%d",ESTATE_MAX_ACCESS_IDS); + args["LIST_TYPE"] = LLTrans::getString("RegionInfoListTypeAllowedAgents"); + args["NUM_EXCESS"] = llformat("%d",(ids.size()+currentCount)-ESTATE_MAX_ACCESS_IDS); + LLNotificationsUtil::add("MaxAgentOnRegionBatch", args); + delete change_info; + return; + } + + uuid_vec_t ids_allowed; + std::vector names_allowed; + std::string already_allowed; + bool single = true; + for (U32 i = 0; i < ids.size(); ++i) + { + LLScrollListItem* item = name_list->getNameItemByAgentId(ids[i]); + if (item) + { + if (!already_allowed.empty()) + { + already_allowed += ", "; + single = false; + } + already_allowed += item->getColumn(0)->getValue().asString(); + } + else + { + ids_allowed.push_back(ids[i]); + names_allowed.push_back(names[i]); + } + } + if (!already_allowed.empty()) + { + LLSD args; + args["AGENT"] = already_allowed; + args["LIST_TYPE"] = LLTrans::getString("RegionInfoListTypeAllowedAgents"); + LLNotificationsUtil::add(single ? "AgentIsAlreadyInList" : "AgentsAreAlreadyInList", args); + if (ids_allowed.empty()) + { + delete change_info; + return; + } + } + change_info->mAgentOrGroupIDs = ids_allowed; + change_info->mAgentNames = names_allowed; + } + if (change_info->mOperationFlag & ESTATE_ACCESS_BANNED_AGENT_ADD) + { + LLNameListCtrl* name_list = panel->getChild("banned_avatar_name_list"); + LLNameListCtrl* em_list = panel->getChild("estate_manager_name_list"); + int currentCount = (name_list ? name_list->getItemCount() : 0); + if (ids.size() + currentCount > ESTATE_MAX_ACCESS_IDS) + { + LLSD args; + args["NUM_ADDED"] = llformat("%d",ids.size()); + args["MAX_AGENTS"] = llformat("%d",ESTATE_MAX_ACCESS_IDS); + args["LIST_TYPE"] = LLTrans::getString("RegionInfoListTypeBannedAgents"); + args["NUM_EXCESS"] = llformat("%d",(ids.size()+currentCount)-ESTATE_MAX_ACCESS_IDS); + LLNotificationsUtil::add("MaxAgentOnRegionBatch", args); + delete change_info; + return; + } + + uuid_vec_t ids_allowed; + std::vector names_allowed; + std::string already_banned; + std::string em_ban; + bool single = true; + for (U32 i = 0; i < ids.size(); ++i) + { + bool is_allowed = true; + LLScrollListItem* em_item = em_list->getNameItemByAgentId(ids[i]); + if (em_item) + { + if (!em_ban.empty()) + { + em_ban += ", "; + } + em_ban += em_item->getColumn(0)->getValue().asString(); + is_allowed = false; + } + + LLScrollListItem* item = name_list->getNameItemByAgentId(ids[i]); + if (item) + { + if (!already_banned.empty()) + { + already_banned += ", "; + single = false; + } + already_banned += item->getColumn(0)->getValue().asString(); + is_allowed = false; + } + + if (is_allowed) + { + ids_allowed.push_back(ids[i]); + names_allowed.push_back(names[i]); + } + } + if (!em_ban.empty()) + { + LLSD args; + args["AGENT"] = em_ban; + LLNotificationsUtil::add("ProblemBanningEstateManager", args); + if (ids_allowed.empty()) + { + delete change_info; + return; + } + } + if (!already_banned.empty()) + { + LLSD args; + args["AGENT"] = already_banned; + args["LIST_TYPE"] = LLTrans::getString("RegionInfoListTypeBannedAgents"); + LLNotificationsUtil::add(single ? "AgentIsAlreadyInList" : "AgentsAreAlreadyInList", args); + if (ids_allowed.empty()) + { + delete change_info; + return; + } + } + change_info->mAgentOrGroupIDs = ids_allowed; + change_info->mAgentNames = names_allowed; + } + + LLSD args; + args["ALL_ESTATES"] = all_estates_text(); + LLNotification::Params params(change_info->mDialogName); + params.substitutions(args) + .payload(change_info->asLLSD()) + .functor(accessCoreConfirm); + + if (LLPanelEstateInfo::isLindenEstate()) + { + // just apply to this estate + LLNotifications::instance().forceResponse(params, 0); + } + else + { + // ask if this estate or all estates with this owner + LLNotifications::instance().add(params); + } +} + +// static +void LLPanelEstateAccess::accessRemoveCore(U32 operation_flag, const std::string& dialog_name, const std::string& list_ctrl_name) +{ + LLPanelEstateAccess* panel = LLFloaterRegionInfo::getPanelAccess(); + if (!panel) return; + LLNameListCtrl* name_list = panel->getChild(list_ctrl_name); + if (!name_list) return; + + std::vector list_vector = name_list->getAllSelected(); + if (list_vector.size() == 0) + return; + + LLSD payload; + payload["operation"] = (S32)operation_flag; + payload["dialog_name"] = dialog_name; + + for (std::vector::const_iterator iter = list_vector.begin(); + iter != list_vector.end(); + iter++) + { + LLScrollListItem *item = (*iter); + payload["allowed_ids"].append(item->getUUID()); + } + + LLNotification::Params params("ChangeLindenAccess"); + params.payload(payload) + .functor(accessRemoveCore2); + + if (LLPanelEstateInfo::isLindenEstate()) + { + // warn on change linden estate + LLNotifications::instance().add(params); + } + else + { + // just proceed, as if clicking OK + LLNotifications::instance().forceResponse(params, 0); + } +} + +// static +bool LLPanelEstateAccess::accessRemoveCore2(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + if (option != 0) + { + // abort + return false; + } + + // If Linden estate, can only apply to "this" estate, not all estates + // owned by NULL. + if (LLPanelEstateInfo::isLindenEstate()) + { + accessCoreConfirm(notification, response); + } + else + { + LLSD args; + args["ALL_ESTATES"] = all_estates_text(); + LLNotificationsUtil::add(notification["payload"]["dialog_name"], + args, + notification["payload"], + accessCoreConfirm); + } + return false; +} + +// Used for both access add and remove operations, depending on the mOperationFlag +// passed in (ESTATE_ACCESS_BANNED_AGENT_ADD, ESTATE_ACCESS_ALLOWED_AGENT_REMOVE, etc.) +// static +bool LLPanelEstateAccess::accessCoreConfirm(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + const U32 originalFlags = (U32)notification["payload"]["operation"].asInteger(); + U32 flags = originalFlags; + + LLViewerRegion* region = gAgent.getRegion(); + + if (option == 2) // cancel + { + return false; + } + else if (option == 1) + { + // All estates, either than I own or manage for this owner. + // This will be verified on simulator. JC + if (!region) return false; + if (region->getOwner() == gAgent.getID() + || gAgent.isGodlike()) + { + flags |= ESTATE_ACCESS_APPLY_TO_ALL_ESTATES; + } + else if (region->isEstateManager()) + { + flags |= ESTATE_ACCESS_APPLY_TO_MANAGED_ESTATES; + } + } + + std::string names; + U32 listed_names = 0; + const auto& ids = notification["payload"]["allowed_ids"]; + const auto& allowed_names = notification["payload"]["allowed_names"]; + U32 size = ids.size(); + for (U32 i = 0; i < size; ++i) + { + if (i + 1 != size) + { + flags |= ESTATE_ACCESS_NO_REPLY; + } + else + { + flags &= ~ESTATE_ACCESS_NO_REPLY; + } + + const LLUUID id = ids[i].asUUID(); + if (((U32)notification["payload"]["operation"].asInteger() & ESTATE_ACCESS_BANNED_AGENT_ADD) + && region && (region->getOwner() == id)) + { + LLNotificationsUtil::add("OwnerCanNotBeDenied"); + break; + } + + sendEstateAccessDelta(flags, id); + + if ((flags & (ESTATE_ACCESS_ALLOWED_GROUP_ADD | ESTATE_ACCESS_ALLOWED_GROUP_REMOVE)) == 0) + { + // fill the name list for confirmation + if (listed_names < MAX_LISTED_NAMES) + { + if (!names.empty()) + { + names += ", "; + } + const auto& display_name = allowed_names[i]["display_name"].asStringRef(); + if (!display_name.empty()) + { + names += display_name; + } + else + { //try to get an agent name from cache + LLAvatarName av_name; + if (LLAvatarNameCache::get(id, &av_name)) + { + names += av_name.getCompleteName(); + } + } + + } + listed_names++; + } + } + if (listed_names > MAX_LISTED_NAMES) + { + LLSD args; + args["EXTRA_COUNT"] = llformat("%d", listed_names - MAX_LISTED_NAMES); + names += " " + LLTrans::getString("AndNMore", args); + } + + if (!names.empty()) // show the conirmation + { + LLSD args; + args["AGENT"] = names; + + if (flags & (ESTATE_ACCESS_ALLOWED_AGENT_ADD | ESTATE_ACCESS_ALLOWED_AGENT_REMOVE)) + { + args["LIST_TYPE"] = LLTrans::getString("RegionInfoListTypeAllowedAgents"); + } + else if (flags & (ESTATE_ACCESS_BANNED_AGENT_ADD | ESTATE_ACCESS_BANNED_AGENT_REMOVE)) + { + args["LIST_TYPE"] = LLTrans::getString("RegionInfoListTypeBannedAgents"); + } + + if (flags & ESTATE_ACCESS_APPLY_TO_ALL_ESTATES) + { + args["ESTATE"] = LLTrans::getString("RegionInfoAllEstates"); + } + else if (flags & ESTATE_ACCESS_APPLY_TO_MANAGED_ESTATES) + { + args["ESTATE"] = LLTrans::getString("RegionInfoManagedEstates"); + } + else + { + args["ESTATE"] = LLTrans::getString("RegionInfoThisEstate"); + } + + bool single = (listed_names == 1); + if (flags & (ESTATE_ACCESS_ALLOWED_AGENT_ADD | ESTATE_ACCESS_BANNED_AGENT_ADD)) + { + LLNotificationsUtil::add(single ? "AgentWasAddedToList" : "AgentsWereAddedToList", args); + } + else if (flags & (ESTATE_ACCESS_ALLOWED_AGENT_REMOVE | ESTATE_ACCESS_BANNED_AGENT_REMOVE)) + { + LLNotificationsUtil::add(single ? "AgentWasRemovedFromList" : "AgentsWereRemovedFromList", args); + } + } + + LLPanelEstateAccess* panel = LLFloaterRegionInfo::getPanelAccess(); + if (panel) + { + panel->setPendingUpdate(true); + } + + return false; +} + +// key = "estateaccessdelta" +// str(estate_id) will be added to front of list by forward_EstateOwnerRequest_to_dataserver +// str[0] = str(agent_id) requesting the change +// str[1] = str(flags) (ESTATE_ACCESS_DELTA_*) +// str[2] = str(agent_id) to add or remove +// static +void LLPanelEstateAccess::sendEstateAccessDelta(U32 flags, const LLUUID& agent_or_group_id) +{ + LLMessageSystem* msg = gMessageSystem; + msg->newMessage("EstateOwnerMessage"); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null); //not used + + msg->nextBlock("MethodData"); + msg->addString("Method", "estateaccessdelta"); + msg->addUUID("Invoice", LLFloaterRegionInfo::getLastInvoice()); + + std::string buf; + gAgent.getID().toString(buf); + msg->nextBlock("ParamList"); + msg->addString("Parameter", buf); + + buf = llformat("%u", flags); + msg->nextBlock("ParamList"); + msg->addString("Parameter", buf); + + agent_or_group_id.toString(buf); + msg->nextBlock("ParamList"); + msg->addString("Parameter", buf); + + + if (flags & (ESTATE_ACCESS_ALLOWED_AGENT_ADD | ESTATE_ACCESS_ALLOWED_AGENT_REMOVE | + ESTATE_ACCESS_BANNED_AGENT_ADD | ESTATE_ACCESS_BANNED_AGENT_REMOVE)) + { + if (auto panel = LLFloaterRegionInfo::getPanelAccess()) + { + // Clear these out before we ask for an update + if (auto name_list = panel->getChild("allowed_avatar_name_list")) + name_list->deleteAllItems(); + if (auto name_list = panel->getChild("banned_avatar_name_list")) + name_list->deleteAllItems(); + } + } + + gAgent.sendReliableMessage(); +} + +void LLPanelEstateAccess::updateChild(LLUICtrl* child_ctrl) +{ + // Ensure appropriate state of the management ui. + updateControls(gAgent.getRegion()); +} + +struct RequestEstateGetAccessResponder : public LLHTTPClient::ResponderWithCompleted +{ + void httpCompleted() override + { + LLPanelEstateAccess::onEstateAccessReceived(mContent); + } + char const* getName() const override { return "requestEstateGetAccessCoro"; } +}; + +void LLPanelEstateAccess::updateLists() +{ + std::string cap_url = gAgent.getRegionCapability("EstateAccess"); + if (!cap_url.empty()) + { + LLHTTPClient::get(cap_url, new RequestEstateGetAccessResponder); + } +} +/* + LLCoros::instance().launch("LLFloaterRegionInfo::requestEstateGetAccessCoro", boost::bind(LLPanelEstateAccess::requestEstateGetAccessCoro, cap_url)); + } +} + +void LLPanelEstateAccess::requestEstateGetAccessCoro(std::string url) +{ + LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); + LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("requestEstateGetAccessoCoro", httpPolicy)); + LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); + + LLSD result = httpAdapter->getAndSuspend(httpRequest, url); + + LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; + LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); + + onEstateAccessReceived(result); +} +*/ + +void LLPanelEstateAccess::onEstateAccessReceived(const LLSD& result) +{ + LLPanelEstateAccess* panel = LLFloaterRegionInfo::getPanelAccess(); + if (!panel) return; + + LLNameListCtrl* allowed_agent_name_list = panel->getChild("allowed_avatar_name_list"); + if (allowed_agent_name_list && result.has("AllowedAgents")) + { + LLStringUtil::format_map_t args; + args["[ALLOWEDAGENTS]"] = llformat("%d", result["AllowedAgents"].size()); + args["[MAXACCESS]"] = llformat("%d", ESTATE_MAX_ACCESS_IDS); + std::string msg = LLTrans::getString("RegionInfoAllowedResidents", args); + panel->getChild("allow_resident_label")->setValue(LLSD(msg)); + + const auto order = allowed_agent_name_list->getSortOrder(); + allowed_agent_name_list->clearSortOrder(); + allowed_agent_name_list->deleteAllItems(); + for (LLSD::array_const_iterator it = result["AllowedAgents"].beginArray(); it != result["AllowedAgents"].endArray(); ++it) + { + LLUUID id = (*it)["id"].asUUID(); + allowed_agent_name_list->addNameItem(id); + } + allowed_agent_name_list->setSortOrder(order); + } + + LLNameListCtrl* banned_agent_name_list = panel->getChild("banned_avatar_name_list"); + if (banned_agent_name_list && result.has("BannedAgents")) + { + LLStringUtil::format_map_t args; + args["[BANNEDAGENTS]"] = llformat("%d", result["BannedAgents"].size()); + args["[MAXBANNED]"] = llformat("%d", ESTATE_MAX_ACCESS_IDS); + std::string msg = LLTrans::getString("RegionInfoBannedResidents", args); + panel->getChild("ban_resident_label")->setValue(LLSD(msg)); + + const auto order = banned_agent_name_list->getSortOrder(); + banned_agent_name_list->clearSortOrder(); + banned_agent_name_list->deleteAllItems(); + static const auto na = LLTrans::getString("na"); + for (LLSD::array_const_iterator it = result["BannedAgents"].beginArray(); it != result["BannedAgents"].endArray(); ++it) + { + LLSD item; + item["id"] = (*it)["id"].asUUID(); + LLSD& columns = item["columns"]; + + columns[0]["column"] = "name"; // to be populated later + + columns[1]["column"] = "last_login_date"; + columns[1]["value"] = (*it)["last_login_date"].asString().substr(0, 16); // cut the seconds + + std::string ban_date = (*it)["ban_date"].asString(); + columns[2]["column"] = "ban_date"; + columns[2]["value"] = ban_date[0] != '0' ? ban_date.substr(0, 16) : na; // server returns the "0000-00-00 00:00:00" date in case it doesn't know it + + columns[3]["column"] = "bannedby"; + LLUUID banning_id = (*it)["banning_id"].asUUID(); + LLAvatarName av_name; + if (banning_id.isNull()) + { + columns[3]["value"] = na; + } + else if (LLAvatarNameCache::get(banning_id, &av_name)) + { + columns[3]["value"] = av_name.getCompleteName(); //TODO: fetch the name if it wasn't cached + } + + banned_agent_name_list->addElement(item); + } + banned_agent_name_list->setSortOrder(order); + } + + LLNameListCtrl* allowed_group_name_list = panel->getChild("allowed_group_name_list"); + if (allowed_group_name_list && result.has("AllowedGroups")) + { + LLStringUtil::format_map_t args; + args["[ALLOWEDGROUPS]"] = llformat("%d", result["AllowedGroups"].size()); + args["[MAXACCESS]"] = llformat("%d", ESTATE_MAX_GROUP_IDS); + std::string msg = LLTrans::getString("RegionInfoAllowedGroups", args); + panel->getChild("allow_group_label")->setValue(LLSD(msg)); + + const auto order = allowed_group_name_list->getSortOrder(); + allowed_group_name_list->clearSortOrder(); + allowed_group_name_list->deleteAllItems(); + for (LLSD::array_const_iterator it = result["AllowedGroups"].beginArray(); it != result["AllowedGroups"].endArray(); ++it) + { + LLUUID id = (*it)["id"].asUUID(); + allowed_group_name_list->addGroupNameItem(id); + } + allowed_group_name_list->setSortOrder(order); + } + + LLNameListCtrl* estate_manager_name_list = panel->getChild("estate_manager_name_list"); + if (estate_manager_name_list && result.has("Managers")) + { + LLStringUtil::format_map_t args; + args["[ESTATEMANAGERS]"] = llformat("%d", result["Managers"].size()); + args["[MAXMANAGERS]"] = llformat("%d", ESTATE_MAX_MANAGERS); + std::string msg = LLTrans::getString("RegionInfoEstateManagers", args); + panel->getChild("estate_manager_label")->setValue(LLSD(msg)); + + const auto order = estate_manager_name_list->getSortOrder(); + estate_manager_name_list->clearSortOrder(); + estate_manager_name_list->deleteAllItems(); + for (LLSD::array_const_iterator it = result["Managers"].beginArray(); it != result["Managers"].endArray(); ++it) + { + LLUUID id = (*it)["agent_id"].asUUID(); + estate_manager_name_list->addNameItem(id); + } + estate_manager_name_list->setSortOrder(order); + } + + + panel->updateControls(gAgent.getRegion()); +} + +//--------------------------------------------------------------------------- +// Access lists search +//--------------------------------------------------------------------------- +void LLPanelEstateAccess::onAllowedSearchEdit(const std::string& search_string) +{ + LLPanelEstateAccess* panel = LLFloaterRegionInfo::getPanelAccess(); + if (!panel) return; + LLNameListCtrl* allowed_agent_name_list = panel->getChild("allowed_avatar_name_list"); + searchAgent(allowed_agent_name_list, search_string); +} + +void LLPanelEstateAccess::onAllowedGroupsSearchEdit(const std::string& search_string) +{ + LLPanelEstateAccess* panel = LLFloaterRegionInfo::getPanelAccess(); + if (!panel) return; + LLNameListCtrl* allowed_group_name_list = panel->getChild("allowed_group_name_list"); + searchAgent(allowed_group_name_list, search_string); +} + +void LLPanelEstateAccess::onBannedSearchEdit(const std::string& search_string) +{ + LLPanelEstateAccess* panel = LLFloaterRegionInfo::getPanelAccess(); + if (!panel) return; + LLNameListCtrl* banned_agent_name_list = panel->getChild("banned_avatar_name_list"); + searchAgent(banned_agent_name_list, search_string); +} + +void LLPanelEstateAccess::searchAgent(LLNameListCtrl* listCtrl, const std::string& search_string) +{ + if (!listCtrl) return; + listCtrl->setFilter(search_string); +} + +void LLPanelEstateAccess::copyListToClipboard(std::string list_name) +{ + LLPanelEstateAccess* panel = LLFloaterRegionInfo::getPanelAccess(); + if (!panel) return; + LLNameListCtrl* name_list = panel->getChild(list_name); + if (!name_list) return; + + std::vector list_vector = name_list->getAllData(); + if (list_vector.size() == 0) return; + + LLSD::String list_to_copy; + for (std::vector::const_iterator iter = list_vector.begin(); + iter != list_vector.end(); + iter++) + { + LLScrollListItem *item = (*iter); + if (item) + { + list_to_copy += item->getColumn(0)->getValue().asString(); + } + if (std::next(iter) != list_vector.end()) + { + list_to_copy += '\n'; + } + } + + auto wstr = utf8str_to_wstring(list_to_copy); + gClipboard.copyFromSubstring(wstr, 0, wstr.length()); +} + +bool LLPanelEstateAccess::refreshFromRegion(LLViewerRegion* region) +{ + // Clear these out before we ask for an update + if (auto name_list = getChild("allowed_avatar_name_list")) + name_list->deleteAllItems(); + if (auto name_list = getChild("banned_avatar_name_list")) + name_list->deleteAllItems(); + + updateLists(); + return LLPanelRegionInfo::refreshFromRegion(region); +} + + // [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a) void LLFloaterRegionInfo::open() { diff --git a/indra/newview/llfloaterregioninfo.h b/indra/newview/llfloaterregioninfo.h index beb6893e1..58141e930 100644 --- a/indra/newview/llfloaterregioninfo.h +++ b/indra/newview/llfloaterregioninfo.h @@ -35,6 +35,7 @@ #define LL_LLFLOATERREGIONINFO_H #include +#include "llagent.h" #include "llfloater.h" #include "llpanel.h" @@ -63,15 +64,17 @@ class LLPanelRegionDebugInfo; class LLPanelRegionTerrainInfo; class LLPanelEstateInfo; class LLPanelEstateCovenant; +class LLPanelEstateAccess; class LLFloaterRegionInfo : public LLFloater, public LLFloaterSingleton { - friend class LLUISingleton >; + friend class LLUISingleton>; public: /*virtual*/ void onOpen(); + /*virtual*/ void onClose(bool app_quitting); /*virtual*/ BOOL postBuild(); // [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a) /*virtual*/ void open(); @@ -88,6 +91,7 @@ public: //static void incrementSerial() { sRequestSerial++; } static LLPanelEstateInfo* getPanelEstate(); + static LLPanelEstateAccess* getPanelAccess(); static LLPanelEstateCovenant* getPanelCovenant(); static LLPanelRegionTerrainInfo* getPanelRegionTerrain(); @@ -106,6 +110,7 @@ protected: protected: void onTabSelected(const LLSD& param); void refreshFromRegion(LLViewerRegion* region); + void onGodLevelChange(U8 god_level); // member data LLTabContainer* mTab; @@ -113,6 +118,10 @@ protected: info_panels_t mInfoPanels; //static S32 sRequestSerial; // serial # of last EstateOwnerRequest static LLUUID sRequestInvoice; + +private: + LLAgent::god_level_change_slot_t mGodLevelChangeSlot; + }; @@ -261,41 +270,18 @@ public: void onChangeFixedSun(); void onChangeUseGlobalTime(); + void onChangeAccessOverride(); void onClickEditSky(); void onClickEditSkyHelp(); void onClickEditDayCycle(); void onClickEditDayCycleHelp(); - void onClickAddAllowedAgent(); - void onClickRemoveAllowedAgent(); - void onClickAddAllowedGroup(); - void onClickRemoveAllowedGroup(); - void onClickAddBannedAgent(); - void onClickRemoveBannedAgent(); - void onClickAddEstateManager(); - void onClickRemoveEstateManager(); void onClickKickUser(); - // Group picker callback is different, can't use core methods below - bool addAllowedGroup(const LLSD& notification, const LLSD& response); - void addAllowedGroup2(LLUUID id); - // Core methods for all above add/remove button clicks - static void accessAddCore(U32 operation_flag, const std::string& dialog_name); - static bool accessAddCore2(const LLSD& notification, const LLSD& response); - static void accessAddCore3(const uuid_vec_t& ids, LLEstateAccessChangeInfo* change_info); - - static void accessRemoveCore(U32 operation_flag, const std::string& dialog_name, const std::string& list_ctrl_name); - static bool accessRemoveCore2(const LLSD& notification, const LLSD& response); - - // used for both add and remove operations - static bool accessCoreConfirm(const LLSD& notification, const LLSD& response); bool kickUserConfirm(const LLSD& notification, const LLSD& response); - // Send the actual EstateOwnerRequest "estateaccessdelta" message - static void sendEstateAccessDelta(U32 flags, const LLUUID& agent_id); - void onKickUserCommit(const uuid_vec_t& ids, const std::vector& names); static void onClickMessageEstate(void* data); bool onMessageCommit(const LLSD& notification, const LLSD& response); @@ -331,7 +317,6 @@ protected: void commitEstateAccess(); void commitEstateManagers(); - void clearAccessLists(); BOOL checkSunHourSlider(LLUICtrl* child_ctrl); U32 mEstateID; @@ -410,8 +395,6 @@ public: // LLPanel /*virtual*/ BOOL postBuild(); - - // LLPanelRegionInfo /*virtual*/ void onOpen(const LLSD& key); // LLView @@ -463,4 +446,104 @@ private: LLComboBox* mDayCyclePresetCombo; }; +#if 0 // Singu TODO: Experiences +class LLPanelRegionExperiences : public LLPanelRegionInfo +{ + LOG_CLASS(LLPanelEnvironmentInfo); + +public: + LLPanelRegionExperiences(); + /*virtual*/ BOOL postBuild() override; + BOOL sendUpdate() override; + + static bool experienceCoreConfirm(const LLSD& notification, const LLSD& response); + static void sendEstateExperienceDelta(U32 flags, const LLUUID& agent_id); + + static void infoCallback(LLHandle handle, const LLSD& content); + bool refreshFromRegion(LLViewerRegion* region) override; + void sendPurchaseRequest()const; + void processResponse( const LLSD& content ); +private: + void refreshRegionExperiences(); + + static std::string regionCapabilityQuery(LLViewerRegion* region, const std::string &cap); + + void setupList(LLPanelExperienceListEditor* child, const char* control_name, U32 add_id, U32 remove_id); + static LLSD addIds( LLPanelExperienceListEditor* panel ); + + void itemChanged(U32 event_type, const LLUUID& id); + + LLPanelExperienceListEditor* mTrusted; + LLPanelExperienceListEditor* mAllowed; + LLPanelExperienceListEditor* mBlocked; + LLUUID mDefaultExperience; +}; + +#endif // Singu TODO: Experiences + +class LLPanelEstateAccess : public LLPanelRegionInfo +{ + LOG_CLASS(LLPanelEnvironmentInfo); + +public: + LLPanelEstateAccess(); + + virtual BOOL postBuild(); + virtual void updateChild(LLUICtrl* child_ctrl); + + void updateControls(LLViewerRegion* region); + void updateLists(); + + void setPendingUpdate(bool pending) { mPendingUpdate = pending; } + bool getPendingUpdate() { return mPendingUpdate; } + + virtual bool refreshFromRegion(LLViewerRegion* region); + + static void onEstateAccessReceived(const LLSD& result); + +private: + void onClickAddAllowedAgent(); + void onClickRemoveAllowedAgent(); + void onClickCopyAllowedList(); + void onClickAddAllowedGroup(); + void onClickRemoveAllowedGroup(); + void onClickCopyAllowedGroupList(); + void onClickAddBannedAgent(); + void onClickRemoveBannedAgent(); + void onClickCopyBannedList(); + void onClickAddEstateManager(); + void onClickRemoveEstateManager(); + void onAllowedSearchEdit(const std::string& search_string); + void onAllowedGroupsSearchEdit(const std::string& search_string); + void onBannedSearchEdit(const std::string& search_string); + + // Group picker callback is different, can't use core methods below + bool addAllowedGroup(const LLSD& notification, const LLSD& response); + void addAllowedGroup2(LLUUID id); + + // Core methods for all above add/remove button clicks + static void accessAddCore(U32 operation_flag, const std::string& dialog_name); + static bool accessAddCore2(const LLSD& notification, const LLSD& response); + static void accessAddCore3(const uuid_vec_t& ids, const std::vector& names, LLEstateAccessChangeInfo* change_info); + + static void accessRemoveCore(U32 operation_flag, const std::string& dialog_name, const std::string& list_ctrl_name); + static bool accessRemoveCore2(const LLSD& notification, const LLSD& response); + + // used for both add and remove operations + static bool accessCoreConfirm(const LLSD& notification, const LLSD& response); + +public: + // Send the actual EstateOwnerRequest "estateaccessdelta" message + static void sendEstateAccessDelta(U32 flags, const LLUUID& agent_id); + +private: + //static void requestEstateGetAccessCoro(std::string url); + + void searchAgent(LLNameListCtrl* listCtrl, const std::string& search_string); + void copyListToClipboard(std::string list_name); + + bool mPendingUpdate; + bool mCtrlsEnabled; +}; + #endif diff --git a/indra/newview/llfloatertos.cpp b/indra/newview/llfloatertos.cpp index aeb1c0105..50b261e68 100644 --- a/indra/newview/llfloatertos.cpp +++ b/indra/newview/llfloatertos.cpp @@ -1,34 +1,33 @@ /** - * @file llfloatertos.cpp - * @brief Terms of Service Agreement dialog - * - * $LicenseInfo:firstyear=2003&license=viewergpl$ - * - * Copyright (c) 2003-2009, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ +* @file llfloatertos.cpp +* @brief Terms of Service Agreement dialog +* +* $LicenseInfo:firstyear=2003&license=viewergpl$ +* +* Copyright (c) 2003-2009, Linden Research, Inc.; 2010, McCabe Maxsted; 2019, Liru Faers +* +* Second Life Viewer Source Code +* The source code in this file ("Source Code") is provided by Linden Lab +* to you under the terms of the GNU General Public License, version 2.0 +* ("GPL"), unless you have obtained a separate licensing agreement +* ("Other License"), formally executed by you and Linden Lab. Terms of +* the GPL can be found in doc/GPL-license.txt in this distribution, or +* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 +* +* There are special exceptions to the terms and conditions of the GPL as +* it is applied to this Source Code. View the full text of the exception +* in the file doc/FLOSS-exception.txt in this software distribution, or +* online at http://secondlifegrid.net/programs/open_source/licensing/flossexception +* +* By copying, modifying or distributing this software, you acknowledge +* that you have read and understood your obligations described above, +* and agree to abide by those obligations. +* +* ALL SOURCE CODE IS PROVIDED "AS IS." THE AUTHOR MAKES NO +* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, +* COMPLETENESS OR PERFORMANCE. +* $/LicenseInfo$ +*/ #include "llviewerprecompiledheaders.h" @@ -58,86 +57,71 @@ class AIHTTPTimeoutPolicy; extern AIHTTPTimeoutPolicy iamHere_timeout; // static -LLFloaterTOS* LLFloaterTOS::sInstance = NULL; +LLFloaterTOS* LLFloaterTOS::sInstance = nullptr; // static LLFloaterTOS* LLFloaterTOS::show(ETOSType type, const std::string & message) { - if( !LLFloaterTOS::sInstance ) - { - LLFloaterTOS::sInstance = new LLFloaterTOS(type, message); - } - - if (type == TOS_TOS) - { - LLUICtrlFactory::getInstance()->buildFloater(LLFloaterTOS::sInstance, "floater_tos.xml"); - } - else - { - LLUICtrlFactory::getInstance()->buildFloater(LLFloaterTOS::sInstance, "floater_critical.xml"); - } - - return LLFloaterTOS::sInstance; + if (sInstance) sInstance->close(); + return sInstance = new LLFloaterTOS(type, message); } -LLFloaterTOS::LLFloaterTOS(ETOSType type, const std::string & message) -: LLModalDialog( std::string(" "), 100, 100 ), +LLFloaterTOS::LLFloaterTOS(ETOSType type, const std::string& message) +: LLModalDialog(std::string(" "), 100, 100), mType(type), - mMessage(message), - mLoadCompleteCount( 0 ) + mLoadCompleteCount(0) { + LLUICtrlFactory::getInstance()->buildFloater(this, + mType == TOS_CRITICAL_MESSAGE ? "floater_critical.xml" + : mType == TOS_TOS ? "floater_tos.xml" + : "floater_voice_license.xml"); + + if (mType == TOS_CRITICAL_MESSAGE) + { + // this displays the critical message + LLTextEditor *editor = getChild("tos_text"); + editor->setHandleEditKeysDirectly(TRUE); + editor->setEnabled(FALSE); + editor->setWordWrap(TRUE); + editor->setFocus(TRUE); + editor->setValue(message); + } } // helper class that trys to download a URL from a web site and calls a method // on parent class indicating if the web server is working or not class LLIamHere : public LLHTTPClient::ResponderWithResult { - private: - LLIamHere( LLFloaterTOS* parent ) : - mParent( parent ) - {} + LLIamHere(LLFloaterTOS* parent) : mParent(parent->getDerivedHandle()) {} + LLHandle mParent; - LLFloaterTOS* mParent; - - public: - - static boost::intrusive_ptr< LLIamHere > build( LLFloaterTOS* parent ) - { - return boost::intrusive_ptr< LLIamHere >( new LLIamHere( parent ) ); - }; +public: + static boost::intrusive_ptr build(LLFloaterTOS* parent) + { + return boost::intrusive_ptr(new LLIamHere(parent)); + } - virtual void setParent( LLFloaterTOS* parentIn ) - { - mParent = parentIn; - }; - - /*virtual*/ void httpSuccess(void) - { - if ( mParent ) - mParent->setSiteIsAlive( true ); - }; + void httpSuccess() override + { + if (!mParent.isDead()) + mParent.get()->setSiteIsAlive(true); + } - /*virtual*/ void httpFailure(void) + void httpFailure() override + { + if (!mParent.isDead()) { - if ( mParent ) - { - // *HACK: For purposes of this alive check, 302 Found - // (aka Moved Temporarily) is considered alive. The web site - // redirects this link to a "cache busting" temporary URL. JC - bool alive = (mStatus == HTTP_FOUND); - mParent->setSiteIsAlive( alive ); - } - }; + // *HACK: For purposes of this alive check, 302 Found + // (aka Moved Temporarily) is considered alive. The web site + // redirects this link to a "cache busting" temporary URL. JC + mParent.get()->setSiteIsAlive(mStatus == HTTP_FOUND); + } + } - /*virtual*/ AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return iamHere_timeout; } - /*virtual*/ bool pass_redirect_status(void) const { return true; } - /*virtual*/ char const* getName(void) const { return "LLIamHere"; } -}; - -// this is global and not a class member to keep crud out of the header file -namespace { - boost::intrusive_ptr< LLIamHere > gResponsePtr = 0; + AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy() const override { return iamHere_timeout; } + bool pass_redirect_status() const override { return true; } + char const* getName() const override { return "LLIamHere"; } }; BOOL LLFloaterTOS::postBuild() @@ -146,78 +130,60 @@ BOOL LLFloaterTOS::postBuild() childSetAction("Cancel", onCancel, this); childSetCommitCallback("agree_chk", updateAgree, this); - if ( mType != TOS_TOS ) - { - // this displays the critical message - LLTextEditor *editor = getChild("tos_text"); - editor->setHandleEditKeysDirectly( TRUE ); - editor->setEnabled( FALSE ); - editor->setWordWrap(TRUE); - editor->setFocus(TRUE); - editor->setValue(LLSD(mMessage)); - - return TRUE; - } + if (mType == TOS_CRITICAL_MESSAGE) return TRUE; // disable Agree to TOS radio button until the page has fully loaded LLCheckBoxCtrl* tos_agreement = getChild("agree_chk"); - tos_agreement->setEnabled( false ); + tos_agreement->setEnabled(false); + bool voice = mType == TOS_VOICE; // hide the SL text widget if we're displaying TOS with using a browser widget. - LLTextEditor *editor = getChild("tos_text"); - editor->setVisible( FALSE ); + getChild(voice ? "license_text" : "tos_text")->setVisible(FALSE); - LLMediaCtrl* web_browser = getChild("tos_html"); - if ( web_browser ) + if (LLMediaCtrl* web_browser = getChild(voice ? "license_html" : "tos_html")) { + // start to observe it so we see navigate complete events web_browser->addObserver(this); - gResponsePtr = LLIamHere::build( this ); - LLHTTPClient::get( getString( "real_url" ), gResponsePtr ); + std::string url = getString( "real_url" ); + if (!voice || url.substr(0,4) == "http") { + LLHTTPClient::get(url, LLIamHere::build(this)); + } else { + setSiteIsAlive(false); + } } return TRUE; } -void LLFloaterTOS::setSiteIsAlive( bool alive ) +void LLFloaterTOS::setSiteIsAlive(bool alive) { // only do this for TOS pages - if ( mType == TOS_TOS ) + if (mType != TOS_CRITICAL_MESSAGE) { - LLMediaCtrl* web_browser = getChild("tos_html"); + bool voice = mType == TOS_VOICE; + LLMediaCtrl* web_browser = getChild(voice ? "license_html" : "tos_html"); // if the contents of the site was retrieved - if ( alive ) + if (alive) { - if ( web_browser ) + if (web_browser) { // navigate to the "real" page - web_browser->navigateTo( getString( "real_url" ) ); - }; + web_browser->navigateTo(getString("real_url")); + } } else { + if (voice) web_browser->navigateToLocalPage("license", getString("fallback_html")); // normally this is set when navigation to TOS page navigation completes (so you can't accept before TOS loads) // but if the page is unavailable, we need to do this now - LLCheckBoxCtrl* tos_agreement = getChild("agree_chk"); - tos_agreement->setEnabled( true ); - }; - }; + getChild("agree_chk")->setEnabled(true); + } + } } LLFloaterTOS::~LLFloaterTOS() { - - // tell the responder we're not here anymore - if ( gResponsePtr ) - gResponsePtr->setParent( 0 ); - - LLFloaterTOS::sInstance = NULL; -} - -// virtual -void LLFloaterTOS::draw() -{ - // draw children - LLModalDialog::draw(); + sInstance = nullptr; } // static @@ -229,11 +195,21 @@ void LLFloaterTOS::updateAgree(LLUICtrl*, void* userdata ) } // static -void LLFloaterTOS::onContinue( void* userdata ) +void LLFloaterTOS::onContinue(void* userdata) { LLFloaterTOS* self = (LLFloaterTOS*) userdata; - LL_INFOS() << "User agrees with TOS." << LL_ENDL; - if (self->mType == TOS_TOS) + bool voice = self->mType == TOS_VOICE; + LL_INFOS() << (voice ? "User agreed to the Vivox personal license" : "User agrees with TOS.") << LL_ENDL; + if (voice) + { + // enabling voice by default here seems like the best behavior + gSavedSettings.setBOOL("EnableVoiceChat", TRUE); + gSavedSettings.setBOOL("VivoxLicenseAccepted", TRUE); + + // save these settings in case something bad happens later + gSavedSettings.saveToFile(gSavedSettings.getString("ClientSettingsFile"), TRUE); + } + else if (self->mType == TOS_TOS) { gAcceptTOS = TRUE; } @@ -242,42 +218,57 @@ void LLFloaterTOS::onContinue( void* userdata ) gAcceptCriticalMessage = TRUE; } + auto state = LLStartUp::getStartupState(); // Testing TOS dialog - #if ! LL_RELEASE_FOR_DOWNLOAD - if ( LLStartUp::getStartupState() == STATE_LOGIN_WAIT ) +#if !LL_RELEASE_FOR_DOWNLOAD + if (!voice && state == STATE_LOGIN_WAIT) { - LLStartUp::setStartupState( STATE_LOGIN_SHOW ); + LLStartUp::setStartupState(STATE_LOGIN_SHOW); } else - #endif - - LLStartUp::setStartupState( STATE_LOGIN_AUTH_INIT ); // Go back and finish authentication +#endif + if (!voice || state == STATE_LOGIN_VOICE_LICENSE) + { + LLStartUp::setStartupState(STATE_LOGIN_AUTH_INIT); // Go back and finish authentication + } self->close(); // destroys this object } // static -void LLFloaterTOS::onCancel( void* userdata ) +void LLFloaterTOS::onCancel(void* userdata) { LLFloaterTOS* self = (LLFloaterTOS*) userdata; - LL_INFOS() << "User disagrees with TOS." << LL_ENDL; - LLNotificationsUtil::add("MustAgreeToLogIn", LLSD(), LLSD(), login_alert_done); - LLStartUp::setStartupState( STATE_LOGIN_SHOW ); - self->mLoadCompleteCount = 0; // reset counter for next time we come to TOS + if (self->mType == TOS_VOICE) + { + LL_INFOS() << "User disagreed with the Vivox personal license" << LL_ENDL; + gSavedSettings.setBOOL("EnableVoiceChat", FALSE); + gSavedSettings.setBOOL("VivoxLicenseAccepted", FALSE); + + if (LLStartUp::getStartupState() == STATE_LOGIN_VOICE_LICENSE) + { + LLStartUp::setStartupState(STATE_LOGIN_AUTH_INIT); // Go back and finish authentication + } + } + else + { + LL_INFOS() << "User disagrees with TOS." << LL_ENDL; + LLNotificationsUtil::add("MustAgreeToLogIn", LLSD(), LLSD(), login_alert_done); + LLStartUp::setStartupState(STATE_LOGIN_SHOW); + } self->close(); // destroys this object } //virtual void LLFloaterTOS::handleMediaEvent(LLPluginClassMedia* /*self*/, EMediaEvent event) { - if(event == MEDIA_EVENT_NAVIGATE_COMPLETE) + if (event == MEDIA_EVENT_NAVIGATE_COMPLETE) { // skip past the loading screen navigate complete - if ( ++mLoadCompleteCount == 2 ) + if (++mLoadCompleteCount == 2) { LL_INFOS() << "NAVIGATE COMPLETE" << LL_ENDL; // enable Agree to TOS radio button now that page has loaded - LLCheckBoxCtrl * tos_agreement = getChild("agree_chk"); - tos_agreement->setEnabled( true ); + getChild("agree_chk")->setEnabled(true); } } } diff --git a/indra/newview/llfloatertos.h b/indra/newview/llfloatertos.h index 331458178..6bfced870 100644 --- a/indra/newview/llfloatertos.h +++ b/indra/newview/llfloatertos.h @@ -24,7 +24,7 @@ * that you have read and understood your obligations described above, * and agree to abide by those obligations. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * ALL SOURCE CODE IS PROVIDED "AS IS." THE AUTHOR MAKES NO * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * COMPLETENESS OR PERFORMANCE. * $/LicenseInfo$ @@ -54,15 +54,13 @@ public: enum ETOSType { TOS_TOS = 0, - TOS_CRITICAL_MESSAGE = 1 + TOS_CRITICAL_MESSAGE = 1, + TOS_VOICE = 2 }; - // Asset_id is overwritten with LLUUID::null when agree is clicked. - static LLFloaterTOS* show(ETOSType type, const std::string & message); + static LLFloaterTOS* show(ETOSType type, const std::string& message = LLStringUtil::null); BOOL postBuild(); - - virtual void draw(); static void updateAgree( LLUICtrl *, void* userdata ); static void onContinue( void* userdata ); @@ -74,12 +72,9 @@ public: /*virtual*/ void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event); private: - // Asset_id is overwritten with LLUUID::null when agree is clicked. - LLFloaterTOS(ETOSType type, const std::string & message); + LLFloaterTOS(ETOSType type, const std::string& message); -private: ETOSType mType; - std::string mMessage; int mLoadCompleteCount; static LLFloaterTOS* sInstance; diff --git a/indra/newview/llfolderviewitem.cpp b/indra/newview/llfolderviewitem.cpp index dab9a1a95..3d1180406 100644 --- a/indra/newview/llfolderviewitem.cpp +++ b/indra/newview/llfolderviewitem.cpp @@ -585,7 +585,7 @@ void LLFolderViewItem::buildContextMenu(LLMenuGL& menu, U32 flags) void LLFolderViewItem::openItem( void ) { if (!mListener) return; - if (mAllowWear || mListener->isItemWearable()) + //if (mAllowWear || mListener->isItemWearable()) // Singu Note: This will do nothing if can't do anything, so just call it { mListener->openItem(); } diff --git a/indra/newview/llgesturemgr.cpp b/indra/newview/llgesturemgr.cpp index d55c22b5e..4c1864185 100644 --- a/indra/newview/llgesturemgr.cpp +++ b/indra/newview/llgesturemgr.cpp @@ -996,9 +996,9 @@ void LLGestureMgr::onLoadComplete(LLVFS *vfs, { LLLoadInfo* info = (LLLoadInfo*)user_data; - const LLUUID& item_id = info->mItemID; - const bool& inform_server = info->mInformServer; - const bool& deactivate_similar = info->mDeactivateSimilar; + const LLUUID item_id = info->mItemID; + const bool inform_server = info->mInformServer; + const bool deactivate_similar = info->mDeactivateSimilar; delete info; info = nullptr; diff --git a/indra/newview/llgesturemgr.h b/indra/newview/llgesturemgr.h index eb23faf69..ff28a164d 100644 --- a/indra/newview/llgesturemgr.h +++ b/indra/newview/llgesturemgr.h @@ -125,7 +125,7 @@ public: bool triggerGesture(KEY key, MASK mask); // Trigger all gestures referenced as substrings in this string - bool triggerAndReviseString(const std::string &str, std::string *revised_string = NULL); + bool triggerAndReviseString(const std::string &str, std::string *revised_string = nullptr); // Does some gesture have this key bound? //bool isKeyBound(KEY key, MASK mask) const; diff --git a/indra/newview/llimpanel.cpp b/indra/newview/llimpanel.cpp index 6334a7f62..7a2349d05 100644 --- a/indra/newview/llimpanel.cpp +++ b/indra/newview/llimpanel.cpp @@ -45,6 +45,7 @@ #include "llfloateravatarpicker.h" #include "llfloaterchat.h" #include "llfloaterinventory.h" +#include "llfloaterreporter.h" #include "llfloaterwebcontent.h" // For web browser display of logs #include "llgroupactions.h" #include "llhttpclient.h" @@ -294,6 +295,7 @@ LLFloaterIMPanel::LLFloaterIMPanel( mLogLabel(log_label), mQueuedMsgsForInit(), mOtherParticipantUUID(other_participant_id), + mInitialTargetIDs(ids), mDialog(dialog), mTyping(false), mTypingLineStartIndex(0), @@ -574,8 +576,19 @@ BOOL LLFloaterIMPanel::postBuild() } break; case SUPPORT_SESSION: - getChildView("Support Check")->setVisible(true); + { + auto support = getChildView("Support Check"); + support->setVisible(true); + auto control = gSavedSettings.getControl(support->getControlName()); + if (control->get().asInteger() == -1) + { + LLNotificationsUtil::add("SupportChatShowInfo", LLSD(), LLSD(), [control](const LLSD& p, const LLSD& f) + { + control->set(!LLNotificationsUtil::getSelectedOption(p, f)); + }); + } // Singu Note: We could make a button feature for dumping Help->About contents for support, too. + } break; default: break; @@ -1121,7 +1134,7 @@ void LLFloaterIMPanel::onFlyoutCommit(LLComboBox* flyout, const LLSD& value) switch (mSessionType) { case SUPPORT_SESSION: - case GROUP_SESSION: LLGroupActions::show(mOtherParticipantUUID); return; + case GROUP_SESSION: LLGroupActions::show(mSessionUUID); return; case P2P_SESSION: LLAvatarActions::showProfile(mOtherParticipantUUID); return; default: onClickHistory(); return; // If there's no profile for this type, we should be the history button. } @@ -1138,6 +1151,7 @@ void LLFloaterIMPanel::onFlyoutCommit(LLComboBox* flyout, const LLSD& value) case -2: LLAvatarActions::showOnMap(mOtherParticipantUUID); break; case -3: gAgentCamera.lookAtObject(mOtherParticipantUUID); break; case -4: onAddButtonClicked(); break; + case -5: LLFloaterReporter::showFromAvatar(mOtherParticipantUUID, mLogLabel); break; default: // Options >= 6 use dynamic items { // First remove them all diff --git a/indra/newview/llimpanel.h b/indra/newview/llimpanel.h index 1fddf5603..a13918f9c 100644 --- a/indra/newview/llimpanel.h +++ b/indra/newview/llimpanel.h @@ -148,6 +148,7 @@ protected: void removeDynamicFocus(); private: + friend class LLSpeakerMgr; // Called by UI methods. void onSendMsg(); @@ -214,6 +215,7 @@ private: // inventory folder ==> first target id in list // 911 ==> sender LLUUID mOtherParticipantUUID; + uuid_vec_t mInitialTargetIDs; EInstantMessage mDialog; diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp index 029a2c4df..fdc576a79 100644 --- a/indra/newview/lllogchat.cpp +++ b/indra/newview/lllogchat.cpp @@ -76,30 +76,41 @@ std::string LLLogChat::cleanFileName(std::string filename) return filename; } +static void time_format(std::string& out, const char* fmt, const std::tm* time) +{ + typedef typename std::vector> vec_t; + static thread_local vec_t charvector(1024); // Evolves into charveleon + #define format_the_time() std::strftime(charvector.data(), charvector.capacity(), fmt, time) + const auto smallsize(charvector.capacity()); + const auto size = format_the_time(); + if (size < 0) + { + LL_ERRS() << "Formatting time failed, code " << size << ". String hint: " << out << '/' << fmt << LL_ENDL; + } + else if (static_cast(size) >= smallsize) // Resize if we need more space + { + charvector.resize(1+size); // Use the String Stone + format_the_time(); + } + out.assign(charvector.data()); +} + + std::string LLLogChat::timestamp(bool withdate) { - time_t utc_time; - utc_time = time_corrected(); - - // There's only one internal tm buffer. - struct tm* timep; - // Convert to Pacific, based on server's opinion of whether // it's daylight savings time there. - timep = utc_to_pacific_time(utc_time, gPacificDaylightTime); + auto time = utc_to_pacific_time(time_corrected(), gPacificDaylightTime); - static LLCachedControl withseconds("SecondsInLog"); - std::string text; - if (withdate) - if (withseconds) - text = llformat("[%d/%02d/%02d %02d:%02d:%02d] ", (timep->tm_year-100)+2000, timep->tm_mon+1, timep->tm_mday, timep->tm_hour, timep->tm_min, timep->tm_sec); - else - text = llformat("[%d/%02d/%02d %02d:%02d] ", (timep->tm_year-100)+2000, timep->tm_mon+1, timep->tm_mday, timep->tm_hour, timep->tm_min); - else - if (withseconds) - text = llformat("[%02d:%02d:%02d] ", timep->tm_hour, timep->tm_min, timep->tm_sec); - else - text = llformat("[%02d:%02d] ", timep->tm_hour, timep->tm_min); + static const LLCachedControl withseconds("SecondsInLog"); + static const LLCachedControl date("ShortDateFormat"); + static const LLCachedControl shorttime("ShortTimeFormat"); + static const LLCachedControl longtime("LongTimeFormat"); + std::string text = "["; + if (withdate) text += date() + ' '; + text += (withseconds ? longtime : shorttime)() + "] "; + + time_format(text, text.data(), time); return text; } diff --git a/indra/newview/llmediactrl.cpp b/indra/newview/llmediactrl.cpp index f9b72c774..df5c51194 100644 --- a/indra/newview/llmediactrl.cpp +++ b/indra/newview/llmediactrl.cpp @@ -54,6 +54,7 @@ #include "llviewermenu.h" // linden library includes +#include "llclipboard.h" #include "llfocusmgr.h" #include "llsdutil.h" #include "lltextbox.h" @@ -397,6 +398,7 @@ void LLMediaCtrl::onFocusLost() BOOL LLMediaCtrl::postBuild () { /*LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registar; + registar.add("Copy.PageURL", boost::bind(&LLMediaCtrl::onCopyURL, this)); registar.add("Open.WebInspector", boost::bind(&LLMediaCtrl::onOpenWebInspector, this)); registar.add("Open.ViewSource", boost::bind(&LLMediaCtrl::onShowSource, this)); @@ -414,6 +416,12 @@ BOOL LLMediaCtrl::postBuild () return true; } +void LLMediaCtrl::onCopyURL() const +{ + auto wurl = utf8str_to_wstring(mCurrentNavUrl); + gClipboard.copyFromSubstring(wurl, 0, wurl.size()); +} + void LLMediaCtrl::onOpenWebInspector() { if (mMediaSource && mMediaSource->hasMedia()) diff --git a/indra/newview/llmediactrl.h b/indra/newview/llmediactrl.h index 6235ee9cb..87c17413f 100644 --- a/indra/newview/llmediactrl.h +++ b/indra/newview/llmediactrl.h @@ -168,6 +168,7 @@ public: // Incoming media event dispatcher void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event) override; + void onCopyURL() const; // right click debugging item void onOpenWebInspector(); void onShowSource(); diff --git a/indra/newview/llmenucommands.cpp b/indra/newview/llmenucommands.cpp index 2246deaff..ae140fa2f 100644 --- a/indra/newview/llmenucommands.cpp +++ b/indra/newview/llmenucommands.cpp @@ -205,7 +205,6 @@ struct MenuFloaterDict : public LLSingleton registerFloater("test", boost::bind(LLFloaterTest::show, (void*)NULL)); // Phoenix: Wolfspirit: Enabled Show Floater out of viewer menu registerFloater("WaterSettings", boost::bind(LLFloaterWater::show), boost::bind(LLFloaterWater::isOpen)); - registerFloater("web", boost::bind(LLFloaterWebContent::showInstance, "dict web", LLFloaterWebContent::Params())); registerFloater("Windlight", boost::bind(LLFloaterWindLight::show), boost::bind(LLFloaterWindLight::isOpen)); registerFloater("world map", boost::bind(LLFloaterWorldMap::toggle)); registerFloater ("about land"); diff --git a/indra/newview/llmimetypes.cpp b/indra/newview/llmimetypes.cpp index 60a50fe7e..697f5e911 100644 --- a/indra/newview/llmimetypes.cpp +++ b/indra/newview/llmimetypes.cpp @@ -35,6 +35,7 @@ #include "llmimetypes.h" #include "lltrans.h" +#include "llxmlnode.h" #include "lluictrlfactory.h" @@ -84,7 +85,7 @@ bool LLMIMETypes::parseMIMETypes(const std::string& xml_filename) } for (LLXMLNode* node = root->getFirstChild(); - node != NULL; + node != nullptr; node = node->getNextSibling()) { if (node->hasName("defaultlabel")) @@ -105,7 +106,7 @@ bool LLMIMETypes::parseMIMETypes(const std::string& xml_filename) node->getAttributeString("name", mime_type); LLMIMEInfo info; for (LLXMLNode* child = node->getFirstChild(); - child != NULL; + child != nullptr; child = child->getNextSibling()) { if (child->hasName("label")) @@ -129,7 +130,7 @@ bool LLMIMETypes::parseMIMETypes(const std::string& xml_filename) node->getAttributeString("name", set_name); LLMIMEWidgetSet info; for (LLXMLNode* child = node->getFirstChild(); - child != NULL; + child != nullptr; child = child->getNextSibling()) { if (child->hasName("label")) diff --git a/indra/newview/llnamelistctrl.cpp b/indra/newview/llnamelistctrl.cpp index 4724eb02a..1e5b950ce 100644 --- a/indra/newview/llnamelistctrl.cpp +++ b/indra/newview/llnamelistctrl.cpp @@ -33,6 +33,8 @@ #include "llavatarnamecache.h" #include "llcachename.h" #include "llagent.h" +#include "llavataractions.h" +#include "llgroupactions.h" #include "llinventory.h" #include "llscrolllistitem.h" #include "llscrolllistcolumn.h" @@ -42,11 +44,11 @@ static LLRegisterWidget r("name_list"); -void LLNameListCtrl::NameTypeNames::declareValues() +void LLNameListItem::NameTypeNames::declareValues() { - declare("INDIVIDUAL", LLNameListCtrl::INDIVIDUAL); - declare("GROUP", LLNameListCtrl::GROUP); - declare("SPECIAL", LLNameListCtrl::SPECIAL); + declare("INDIVIDUAL", INDIVIDUAL); + declare("GROUP", GROUP); + declare("SPECIAL", SPECIAL); } LLNameListCtrl::LLNameListCtrl(const std::string& name, const LLRect& rect, BOOL allow_multiple_selection, BOOL draw_border, bool draw_heading, S32 name_column_index, const std::string& name_system, const std::string& tooltip) @@ -61,16 +63,16 @@ LLNameListCtrl::LLNameListCtrl(const std::string& name, const LLRect& rect, BOOL // public LLScrollListItem* LLNameListCtrl::addNameItem(const LLUUID& agent_id, EAddPosition pos, - BOOL enabled, const std::string& suffix) + BOOL enabled, const std::string& suffix, const std::string& prefix) { //LL_INFOS() << "LLNameListCtrl::addNameItem " << agent_id << LL_ENDL; NameItem item; item.value = agent_id; item.enabled = enabled; - item.target = INDIVIDUAL; + item.target = LLNameListItem::INDIVIDUAL; - return addNameItemRow(item, pos, suffix); + return addNameItemRow(item, pos, suffix, prefix); } // virtual, public @@ -121,6 +123,24 @@ BOOL LLNameListCtrl::handleDragAndDrop( return handled; } +BOOL LLNameListCtrl::handleDoubleClick(S32 x, S32 y, MASK mask) +{ + bool handled = LLScrollListCtrl::handleDoubleClick(x, y, mask); + if (!handled) + { + if (auto item = static_cast(hitItem(x, y))) + { + switch (item->getNameType()) + { + case LLNameListItem::INDIVIDUAL: LLAvatarActions::showProfile(item->getValue()); break; + case LLNameListItem::GROUP: LLGroupActions::show(item->getValue()); break; + default: return false; + } + handled = true; + } + } + return handled; +} // public void LLNameListCtrl::addGroupNameItem(const LLUUID& group_id, EAddPosition pos, @@ -129,7 +149,7 @@ void LLNameListCtrl::addGroupNameItem(const LLUUID& group_id, EAddPosition pos, NameItem item; item.value = group_id; item.enabled = enabled; - item.target = GROUP; + item.target = LLNameListItem::GROUP; addNameItemRow(item, pos); } @@ -137,13 +157,13 @@ void LLNameListCtrl::addGroupNameItem(const LLUUID& group_id, EAddPosition pos, // public void LLNameListCtrl::addGroupNameItem(LLNameListCtrl::NameItem& item, EAddPosition pos) { - item.target = GROUP; + item.target = LLNameListItem::GROUP; addNameItemRow(item, pos); } LLScrollListItem* LLNameListCtrl::addNameItem(LLNameListCtrl::NameItem& item, EAddPosition pos) { - item.target = INDIVIDUAL; + item.target = LLNameListItem::INDIVIDUAL; return addNameItemRow(item, pos); } @@ -160,10 +180,11 @@ LLScrollListItem* LLNameListCtrl::addElement(const LLSD& element, EAddPosition p LLScrollListItem* LLNameListCtrl::addNameItemRow( const LLNameListCtrl::NameItem& name_item, EAddPosition pos, - const std::string& suffix) + const std::string& suffix, + const std::string& prefix) { LLUUID id = name_item.value().asUUID(); - LLNameListItem* item = new LLNameListItem(name_item,name_item.target() == GROUP); + LLNameListItem* item = new LLNameListItem(name_item); if (!item) return NULL; @@ -173,14 +194,25 @@ LLScrollListItem* LLNameListCtrl::addNameItemRow( std::string fullname = name_item.name; switch(name_item.target) { - case GROUP: - gCacheName->getGroupName(id, fullname); - // fullname will be "nobody" if group not found + case LLNameListItem::GROUP: + if (!gCacheName->getGroupName(id, fullname)) + { + avatar_name_cache_connection_map_t::iterator it = mAvatarNameCacheConnections.find(id); + if (it != mAvatarNameCacheConnections.end()) + { + if (it->second.connected()) + { + it->second.disconnect(); + } + mAvatarNameCacheConnections.erase(it); + } + mAvatarNameCacheConnections[id] = gCacheName->getGroup(id, boost::bind(&LLNameListCtrl::onGroupNameCache, this, _1, _2, item->getHandle())); + } break; - case SPECIAL: + case LLNameListItem::SPECIAL: // just use supplied name break; - case INDIVIDUAL: + case LLNameListItem::INDIVIDUAL: { LLAvatarName av_name; if (id.isNull()) @@ -203,12 +235,12 @@ LLScrollListItem* LLNameListCtrl::addNameItemRow( } mAvatarNameCacheConnections.erase(it); } - mAvatarNameCacheConnections[id] = LLAvatarNameCache::get(id,boost::bind(&LLNameListCtrl::onAvatarNameCache,this, _1, _2, suffix, item->getHandle())); + mAvatarNameCacheConnections[id] = LLAvatarNameCache::get(id,boost::bind(&LLNameListCtrl::onAvatarNameCache,this, _1, _2, suffix, prefix, item->getHandle())); if (mPendingLookupsRemaining <= 0) { // BAKER TODO: - // We might get into a state where mPendingLookupsRemainig might + // We might get into a state where mPendingLookupsRemaining might // go negative. So just reset it right now and figure out if it's // possible later :) mPendingLookupsRemaining = 0; @@ -231,7 +263,7 @@ LLScrollListItem* LLNameListCtrl::addNameItemRow( LLScrollListCell* cell = item->getColumn(mNameColumnIndex); if (cell) { - cell->setValue(fullname); + cell->setValue(prefix + fullname); } dirtyColumns(); @@ -271,9 +303,24 @@ void LLNameListCtrl::removeNameItem(const LLUUID& agent_id) } } +// public +LLScrollListItem* LLNameListCtrl::getNameItemByAgentId(const LLUUID& agent_id) +{ + for (item_list::iterator it = getItemList().begin(); it != getItemList().end(); it++) + { + LLScrollListItem* item = *it; + if (item && item->getUUID() == agent_id) + { + return item; + } + } + return NULL; +} + void LLNameListCtrl::onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name, std::string suffix, + std::string prefix, LLHandle item) { avatar_name_cache_connection_map_t::iterator it = mAvatarNameCacheConnections.find(agent_id); @@ -295,6 +342,11 @@ void LLNameListCtrl::onAvatarNameCache(const LLUUID& agent_id, name.append(suffix); } + if (!prefix.empty()) + { + name.insert(0, prefix); + } + LLNameListItem* list_item = item.get(); if (list_item && list_item->getUUID() == agent_id) { @@ -326,6 +378,33 @@ void LLNameListCtrl::onAvatarNameCache(const LLUUID& agent_id, dirtyColumns(); } +void LLNameListCtrl::onGroupNameCache(const LLUUID& group_id, const std::string name, LLHandle item) +{ + avatar_name_cache_connection_map_t::iterator it = mAvatarNameCacheConnections.find(group_id); + if (it != mAvatarNameCacheConnections.end()) + { + if (it->second.connected()) + { + it->second.disconnect(); + } + mAvatarNameCacheConnections.erase(it); + } + + LLNameListItem* list_item = item.get(); + if (list_item && list_item->getUUID() == group_id) + { + LLScrollListCell* cell = list_item->getColumn(mNameColumnIndex); + if (cell) + { + cell->setValue(name); + setNeedsSort(); + } + } + + dirtyColumns(); +} + + void LLNameListCtrl::sortByName(BOOL ascending) { sortByColumnIndex(mNameColumnIndex,ascending); diff --git a/indra/newview/llnamelistctrl.h b/indra/newview/llnamelistctrl.h index 7f6d3763a..4a2bf209a 100644 --- a/indra/newview/llnamelistctrl.h +++ b/indra/newview/llnamelistctrl.h @@ -42,24 +42,47 @@ class LLAvatarName; class LLNameListItem : public LLScrollListItem, public LLHandleProvider { public: - bool isGroup() const { return mIsGroup; } - void setIsGroup(bool is_group) { mIsGroup = is_group; } + enum ENameType + { + INDIVIDUAL, + GROUP, + SPECIAL + }; + + // provide names for enums + struct NameTypeNames : public LLInitParam::TypeValuesHelper + { + static void declareValues(); + }; + + struct Params : public LLInitParam::Block + { + Optional name; + Optional target; + + Params() + : name("name"), + target("target", INDIVIDUAL) + {} + }; + ENameType getNameType() const { return mNameType; } + void setNameType(ENameType name_type) { mNameType = name_type; } protected: friend class LLNameListCtrl; - LLNameListItem( const LLScrollListItem::Params& p ) - : LLScrollListItem(p), mIsGroup(false) + LLNameListItem( const Params& p ) + : LLScrollListItem(p), mNameType(p.target) { } - LLNameListItem( const LLScrollListItem::Params& p, bool is_group ) - : LLScrollListItem(p), mIsGroup(is_group) + LLNameListItem( const LLScrollListItem::Params& p, ENameType name_type) + : LLScrollListItem(p), mNameType(name_type) { } private: - bool mIsGroup; + ENameType mNameType; }; @@ -68,30 +91,7 @@ class LLNameListCtrl { public: typedef boost::signals2::signal namelist_complete_signal_t; - - typedef enum e_name_type - { - INDIVIDUAL, - GROUP, - SPECIAL - } ENameType; - - // provide names for enums - struct NameTypeNames : public LLInitParam::TypeValuesHelper - { - static void declareValues(); - }; - - struct NameItem : public LLInitParam::Block - { - Optional name; - Optional target; - - NameItem() - : name("name"), - target("target", INDIVIDUAL) - {} - }; + typedef LLNameListItem::Params NameItem; struct NameColumn : public LLInitParam::ChoiceBlock { @@ -124,11 +124,12 @@ public: // Add a user to the list by name. It will be added, the name // requested from the cache, and updated as necessary. LLScrollListItem* addNameItem(const LLUUID& agent_id, EAddPosition pos = ADD_BOTTOM, - BOOL enabled = TRUE, const std::string& suffix = LLStringUtil::null); + BOOL enabled = TRUE, const std::string& suffix = LLStringUtil::null, const std::string& prefix = LLStringUtil::null); LLScrollListItem* addNameItem(NameItem& item, EAddPosition pos = ADD_BOTTOM); /*virtual*/ LLScrollListItem* addElement(const LLSD& element, EAddPosition pos = ADD_BOTTOM, void* userdata = NULL); - LLScrollListItem* addNameItemRow(const NameItem& value, EAddPosition pos = ADD_BOTTOM, const std::string& suffix = LLStringUtil::null); + LLScrollListItem* addNameItemRow(const NameItem& value, EAddPosition pos = ADD_BOTTOM, const std::string& suffix = LLStringUtil::null, + const std::string& prefix = LLStringUtil::null); // Add a user to the list by name. It will be added, the name // requested from the cache, and updated as necessary. @@ -139,17 +140,21 @@ public: void removeNameItem(const LLUUID& agent_id); + LLScrollListItem* getNameItemByAgentId(const LLUUID& agent_id); + // LLView interface /*virtual*/ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType cargo_type, void *cargo_data, EAcceptance *accept, std::string& tooltip_msg); + BOOL handleDoubleClick(S32 x, S32 y, MASK mask) override; void setAllowCallingCardDrop(BOOL b) { mAllowCallingCardDrop = b; } void sortByName(BOOL ascending); private: - void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name, std::string suffix, LLHandle item); + void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name, std::string suffix, std::string prefix, LLHandle item); + void onGroupNameCache(const LLUUID& group_id, const std::string name, LLHandle item); private: S32 mNameColumnIndex; diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp index 5871d47bd..c1820c5bd 100644 --- a/indra/newview/llpanelavatar.cpp +++ b/indra/newview/llpanelavatar.cpp @@ -186,7 +186,12 @@ void LLPanelAvatarSecondLife::processProperties(void* data, EAvatarProcessorType args["[PAYMENTINFO]"] = LLAvatarPropertiesProcessor::paymentInfo(pAvatarData); args["[AGEVERIFICATION]"] = LLStringUtil::null; - getChild("acct")->setValue(getString("CaptionTextAcctInfo", args)); + { + const auto account_info = getString("CaptionTextAcctInfo", args); + auto acct = getChild("acct"); + acct->setValue(account_info); + acct->setToolTip(account_info); + } getChild("img")->setImageAssetID(pAvatarData->image_id); @@ -194,11 +199,16 @@ void LLPanelAvatarSecondLife::processProperties(void* data, EAvatarProcessorType { using namespace boost::gregorian; int year, month, day; - sscanf(pAvatarData->born_on.c_str(),"%d/%d/%d", &month, &day, &year); - date birthday(year, month, day), today(day_clock::local_day()); - std::ostringstream born_on; - born_on << pAvatarData->born_on << " (" << today - birthday << ')'; - childSetValue("born", born_on.str()); + const auto& born = pAvatarData->born_on; + if (!born.empty() && sscanf(born.c_str(),"%d/%d/%d", &month, &day, &year) == 3 // Make sure input is valid + && month > 0 && month <= 12 && day > 0 && day <= 31 && year >= 1400) // Don't use numbers that gregorian will choke on + { + date birthday(year, month, day), today(day_clock::local_day()); + std::ostringstream born_on; + born_on << pAvatarData->born_on << " (" << today - birthday << ')'; + childSetValue("born", born_on.str()); + } + else childSetValue("born", born); } bool allow_publish = (pAvatarData->flags & AVATAR_ALLOW_PUBLISH); diff --git a/indra/newview/llpanelgroupgeneral.cpp b/indra/newview/llpanelgroupgeneral.cpp index 192177cc1..4379ff3e1 100644 --- a/indra/newview/llpanelgroupgeneral.cpp +++ b/indra/newview/llpanelgroupgeneral.cpp @@ -43,7 +43,6 @@ #include "llcheckboxctrl.h" #include "llcombobox.h" #include "lldbstrings.h" -#include "llavataractions.h" #include "llgroupactions.h" #include "llimview.h" #include "lllineeditor.h" @@ -159,10 +158,6 @@ BOOL LLPanelGroupGeneral::postBuild() mFounderName = getChild("founder_name"); mListVisibleMembers = getChild("visible_members", recurse); - if (mListVisibleMembers) - { - mListVisibleMembers->setDoubleClickCallback(boost::bind(LLAvatarActions::showProfile, boost::bind(&LLScrollListCtrl::getCurrentID, mListVisibleMembers), false)); - } // Options mCtrlShowInGroupList = getChild("show_in_group_list", recurse); diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp index 6a172cdb3..38fef06e4 100644 --- a/indra/newview/llpanelgrouproles.cpp +++ b/indra/newview/llpanelgrouproles.cpp @@ -34,7 +34,6 @@ #include "llcheckboxctrl.h" #include "llagent.h" -#include "llavataractions.h" #include "llavatarnamecache.h" #include "llbutton.h" #include "llfiltereditor.h" @@ -860,8 +859,6 @@ BOOL LLPanelGroupMembersSubTab::postBuildSubTab(LLView* root) // We want to be notified whenever a member is selected. mMembersList->setCommitOnSelectionChange(TRUE); mMembersList->setCommitCallback(boost::bind(&LLPanelGroupMembersSubTab::onMemberSelect,_1,this)); - // Show the member's profile on double click. - mMembersList->setDoubleClickCallback(boost::bind(&LLPanelGroupMembersSubTab::onMemberDoubleClick,this)); LLButton* button = parent->getChild("member_invite", recurse); if ( button ) @@ -1150,13 +1147,6 @@ void LLPanelGroupMembersSubTab::handleMemberSelect() mEjectBtn->setEnabled(can_eject_members); } -// static -void LLPanelGroupMembersSubTab::onMemberDoubleClick(void* user_data) -{ - LLPanelGroupMembersSubTab* self = static_cast(user_data); - self->handleMemberDoubleClick(); -} - //static void LLPanelGroupMembersSubTab::onInviteMember(void *userdata) { @@ -1334,15 +1324,6 @@ void LLPanelGroupMembersSubTab::onRoleCheck(LLUICtrl* ctrl, void* user_data) } } -void LLPanelGroupMembersSubTab::handleMemberDoubleClick() -{ - LLScrollListItem* selected = mMembersList->getFirstSelected(); - if (selected) - { - LLAvatarActions::showProfile(selected->getUUID()); - } -} - void LLPanelGroupMembersSubTab::activate() { LLPanelGroupSubTab::activate(); diff --git a/indra/newview/llpanelgrouproles.h b/indra/newview/llpanelgrouproles.h index aaf60c7a6..c6fb9871f 100644 --- a/indra/newview/llpanelgrouproles.h +++ b/indra/newview/llpanelgrouproles.h @@ -175,9 +175,6 @@ public: static void onMemberSelect(LLUICtrl*, void*); void handleMemberSelect(); - static void onMemberDoubleClick(void*); - void handleMemberDoubleClick(); - static void onInviteMember(void*); void handleInviteMember(); diff --git a/indra/newview/llprefsvoice.cpp b/indra/newview/llprefsvoice.cpp index 86e39d07d..ccd5743c7 100644 --- a/indra/newview/llprefsvoice.cpp +++ b/indra/newview/llprefsvoice.cpp @@ -35,8 +35,8 @@ #include "llprefsvoice.h" -#include "floatervoicelicense.h" #include "llcheckboxctrl.h" +#include "llfloatertos.h" #include "llfocusmgr.h" #include "llkeyboard.h" #include "llmodaldialog.h" @@ -158,8 +158,9 @@ void LLPrefsVoice::apply() if (enable_voice && !gSavedSettings.getBOOL("VivoxLicenseAccepted")) { // This window enables voice chat if license is accepted - FloaterVoiceLicense::getInstance()->open(); - FloaterVoiceLicense::getInstance()->center(); + auto inst = LLFloaterTOS::show(LLFloaterTOS::TOS_VOICE); + inst->open(); + inst->center(); } else { diff --git a/indra/newview/llspeakers.cpp b/indra/newview/llspeakers.cpp index 64125b1ec..a4e11d815 100644 --- a/indra/newview/llspeakers.cpp +++ b/indra/newview/llspeakers.cpp @@ -561,6 +561,9 @@ void LLSpeakerMgr::update(BOOL resort_ok) void LLSpeakerMgr::updateSpeakerList() { + // Always add the current agent (it has to be there...). Will do nothing if already there. + setSpeaker({ gAgentID, LLSpeaker::SPEAKER_AGENT, LLSpeaker::STATUS_VOICE_ACTIVE }); + // Are we bound to the currently active voice channel? if ((!mVoiceChannel && LLVoiceClient::getInstance()->inProximalChannel()) || (mVoiceChannel && mVoiceChannel->isActive())) { @@ -633,21 +636,19 @@ void LLSpeakerMgr::updateSpeakerList() mSpeakerListUpdated = true; } } - /* Singu TODO: LLIMModel::LLIMSession - else if (mSpeakers.size() == 0) + else if (floater && mSpeakers.size() == 0) { // For all other session type (ad-hoc, P2P, avaline), we use the initial participants targets list - for (uuid_vec_t::iterator it = session->mInitialTargetIDs.begin();it!=session->mInitialTargetIDs.end();++it) + for (const auto& id : floater->mInitialTargetIDs) { // Add buddies if they are on line, add any other avatar. - if (!LLAvatarTracker::instance().isBuddy(*it) || LLAvatarTracker::instance().isBuddyOnline(*it)) + if (!LLAvatarTracker::instance().isBuddy(id) || LLAvatarTracker::instance().isBuddyOnline(id)) { - setSpeaker(*it, "", LLSpeaker::STATUS_VOICE_ACTIVE, LLSpeaker::SPEAKER_AGENT); + setSpeaker({ id, LLSpeaker::SPEAKER_AGENT, LLSpeaker::STATUS_VOICE_ACTIVE }); } } mSpeakerListUpdated = true; } - */ else { // The list has been updated the normal way (i.e. by a ChatterBoxSessionAgentListUpdates received from the server) @@ -655,8 +656,6 @@ void LLSpeakerMgr::updateSpeakerList() } } } - // Always add the current agent (it has to be there...). Will do nothing if already there. - setSpeaker({ gAgentID, LLSpeaker::SPEAKER_AGENT, LLSpeaker::STATUS_VOICE_ACTIVE }); } void LLSpeakerMgr::setSpeakerNotInChannel(LLSpeaker* speakerp) diff --git a/indra/newview/lltoolbar.cpp b/indra/newview/lltoolbar.cpp index ecdcc8062..5a28dfcd6 100644 --- a/indra/newview/lltoolbar.cpp +++ b/indra/newview/lltoolbar.cpp @@ -102,6 +102,7 @@ F32 LLToolBar::sInventoryAutoOpenTime = 1.f; // void show_floater(const std::string& floater_name); void show_inv_floater(const LLSD& userdata, const std::string& field); +void show_web_floater(const std::string& type); LLToolBar::LLToolBar() : LLLayoutPanel() @@ -112,6 +113,7 @@ LLToolBar::LLToolBar() mCommitCallbackRegistrar.add("ShowInvFloater.ID", boost::bind(show_inv_floater, _2, "id")); mCommitCallbackRegistrar.add("ShowInvFloater.Name", boost::bind(show_inv_floater, _2, "name")); mCommitCallbackRegistrar.add("ShowInvFloater.Type", boost::bind(show_inv_floater, _2, "type")); + mCommitCallbackRegistrar.add("ShowWebFloater", boost::bind(show_web_floater, _2)); } diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp index 31ff5334f..9fd131d59 100644 --- a/indra/newview/lltoolpie.cpp +++ b/indra/newview/lltoolpie.cpp @@ -413,7 +413,7 @@ BOOL LLToolPie::handleLeftClickPick() LLToolSelect::handleObjectSelection(mPick, FALSE, TRUE); // Spawn pie menu - LLTool::handleRightMouseDown(x, y, mask); + handleRightMouseDown(x, y, mask); return TRUE; } diff --git a/indra/newview/llviewerfoldertype.cpp b/indra/newview/llviewerfoldertype.cpp index 4ce8d9693..11809193b 100644 --- a/indra/newview/llviewerfoldertype.cpp +++ b/indra/newview/llviewerfoldertype.cpp @@ -133,13 +133,13 @@ LLViewerFolderDictionary::LLViewerFolderDictionary() addEntry(LLFolderType::FT_MY_OUTFITS, new ViewerFolderEntry("My Outfits", "inv_folder_outfit.tga", "inv_folder_outfit.tga", TRUE, false)); addEntry(LLFolderType::FT_MESH, new ViewerFolderEntry("Meshes", "inv_folder_mesh.tga", "inv_folder_mesh.tga", FALSE, false)); - bool boxes_invisible = !gSavedSettings.getBOOL("InventoryOutboxMakeVisible"); + //bool boxes_invisible = !gSavedSettings.getBOOL("InventoryOutboxMakeVisible"); addEntry(LLFolderType::FT_INBOX, new ViewerFolderEntry("Received Items", "inv_folder_inbox.tga", "inv_folder_inbox.tga", FALSE, false)); addEntry(LLFolderType::FT_OUTBOX, new ViewerFolderEntry("Merchant Outbox", "inv_folder_outbox.tga", "inv_folder_outbox.tga", FALSE, true)); addEntry(LLFolderType::FT_BASIC_ROOT, new ViewerFolderEntry("Basic Root", "inv_folder_plain_open.tga", "inv_folder_plain_closed.tga", FALSE, false)); - addEntry(LLFolderType::FT_MARKETPLACE_LISTINGS, new ViewerFolderEntry("Marketplace Listings", "inv_folder_plain_open.tga", "inv_folder_plain_closed.tga", FALSE, boxes_invisible)); + addEntry(LLFolderType::FT_MARKETPLACE_LISTINGS, new ViewerFolderEntry("Marketplace Listings", "inv_folder_plain_open.tga", "inv_folder_plain_closed.tga", FALSE, true)); addEntry(LLFolderType::FT_MARKETPLACE_STOCK, new ViewerFolderEntry("New Stock", "Inv_StockFolderOpen", "Inv_StockFolderClosed", FALSE, false, "default")); addEntry(LLFolderType::FT_MARKETPLACE_VERSION, new ViewerFolderEntry("New Version", "Inv_VersionFolderOpen", "Inv_VersionFolderClosed", FALSE, false, "default")); addEntry(LLFolderType::FT_SUITCASE, new ViewerFolderEntry("My Suitcase", "inv_folder_plain_open.tga", "inv_folder_plain_closed.tga", FALSE, false)); diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 51216eb26..291f0b17b 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -63,6 +63,7 @@ #include "lldebugview.h" #include "llenvmanager.h" #include "llfirstuse.h" +#include "llfloateravatarlist.h" #include "llfloateravatartextures.h" #include "llfloaterbuy.h" #include "llfloaterbuycontents.h" @@ -8988,6 +8989,37 @@ class VisibleInvFloaterType : public view_listener_t } }; +void show_web_floater(const std::string& type) +{ + auto p = LLFloaterWebContent::Params(); + if (!type.empty()) p.id = type; + if (type == "marketplace") + { + if (gHippoGridManager->getConnectedGrid()->isSecondLife()) + p.url = "https://marketplace.secondlife.com"; + else if (LLViewerRegion* region = gAgent.getRegion()) + { + LLSD info; + region->getSimulatorFeatures(info); + p.url = info["MarketplaceURL"]; + } + } + else if (!type.empty() && type != "dict web") + { + p.url = type; // Simple web floaters with direct urls + } + LLFloaterWebContent::showInstance(type, p); +} + +class ShowWebFloater : public view_listener_t +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + show_web_floater(userdata.asStringRef()); + return true; + } +}; + class VisibleSecondLife : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) @@ -9006,30 +9038,36 @@ class VisibleNotSecondLife : public view_listener_t } }; -LLScrollListCtrl* get_focused_list() +template T* get_focused() { - LLScrollListCtrl* list = dynamic_cast(gFocusMgr.getKeyboardFocus()); - llassert(list); // This listener only applies to lists - return list; + T* t = +#ifdef SHOW_ASSERT + dynamic_cast +#else + static_cast +#endif + (gFocusMgr.getKeyboardFocus()); + llassert(t); // This listener only applies to T + return t; } S32 get_focused_list_num_selected() { - if (LLScrollListCtrl* list = get_focused_list()) + if (auto list = get_focused()) return list->getNumSelected(); return 0; } const LLUUID get_focused_list_id_selected() { - if (LLScrollListCtrl* list = get_focused_list()) + if (auto list = get_focused()) return list->getStringUUIDSelectedItem(); return LLUUID::null; } const uuid_vec_t get_focused_list_ids_selected() { - if (LLScrollListCtrl* list = get_focused_list()) + if (auto list = get_focused()) return list->getSelectedIDs(); return uuid_vec_t(); } @@ -9077,7 +9115,7 @@ class ListEnableCall : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - LLScrollListCtrl* list = get_focused_list(); + auto list = get_focused(); if (!list) return false; gMenuHolder->findControl(userdata["control"].asString())->setValue(LLAvatarActions::canCall()); return true; @@ -9224,11 +9262,16 @@ class ListShare : public view_listener_t } }; +bool can_show_web_profile() +{ + return !gSavedSettings.getString("WebProfileURL").empty(); +} + +void show_log_browser(const LLUUID& id); class ListShowLog : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - void show_log_browser(const LLUUID& id); for (const LLUUID& id : get_focused_list_ids_selected()) show_log_browser(id); return true; @@ -9316,24 +9359,50 @@ void parcel_mod_notice_callback(const uuid_vec_t& ids, S32 choice, boost::functi cb(*it, choice); } +bool is_nearby(const LLUUID& id); +class ListIsNearby : public view_listener_t +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + gMenuHolder->findControl(userdata["control"].asString())->setValue(is_nearby(get_focused_list_id_selected())); + return true; + } +}; + +void track_av(const LLUUID& id); +class ListTrack : public view_listener_t +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + track_av(get_focused_list_id_selected()); + return true; + } +}; + void send_eject(const LLUUID& avatar_id, bool ban); +void confirm_eject(const uuid_vec_t& ids) +{ + LLNotificationsUtil::add("EjectAvatarFullname", create_args(ids, "AVATAR_NAME"), LLSD(), boost::bind(parcel_mod_notice_callback, ids, boost::bind(LLNotificationsUtil::getSelectedOption, _1, _2), send_eject)); +} class ListEject : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - const uuid_vec_t& ids = get_focused_list_ids_selected(); - LLNotificationsUtil::add("EjectAvatarFullname", create_args(ids, "AVATAR_NAME"), LLSD(), boost::bind(parcel_mod_notice_callback, ids, boost::bind(LLNotificationsUtil::getSelectedOption, _1, _2), send_eject)); + confirm_eject(get_focused_list_ids_selected()); return true; } }; void send_freeze(const LLUUID& avatar_id, bool freeze); +void confirm_freeze(const uuid_vec_t& ids) +{ + LLNotificationsUtil::add("FreezeAvatarFullname", create_args(ids, "AVATAR_NAME"), LLSD(), boost::bind(parcel_mod_notice_callback, ids, boost::bind(LLNotificationsUtil::getSelectedOption, _1, _2), send_freeze)); +} class ListFreeze : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - const uuid_vec_t& ids = get_focused_list_ids_selected(); - LLNotificationsUtil::add("FreezeAvatarFullname", create_args(ids, "AVATAR_NAME"), LLSD(), boost::bind(parcel_mod_notice_callback, ids, boost::bind(LLNotificationsUtil::getSelectedOption, _1, _2), send_freeze)); + confirm_freeze(get_focused_list_ids_selected()); return true; } }; @@ -9359,27 +9428,33 @@ void estate_bulk_eject(const uuid_vec_t& ids, bool ban, S32 option) else strings.push_back(idstr); if (ban) - LLPanelEstateInfo::sendEstateAccessDelta(ESTATE_ACCESS_BANNED_AGENT_ADD | ESTATE_ACCESS_ALLOWED_AGENT_REMOVE | ESTATE_ACCESS_NO_REPLY, id); + LLPanelEstateAccess::sendEstateAccessDelta(ESTATE_ACCESS_BANNED_AGENT_ADD | ESTATE_ACCESS_ALLOWED_AGENT_REMOVE | ESTATE_ACCESS_NO_REPLY, id); } if (!tphome) send_estate_message("kickestate", strings); } +void confirm_estate_ban(const uuid_vec_t& ids) +{ + LLNotificationsUtil::add("EstateBanUser", create_args(ids, "EVIL_USER"), LLSD(), boost::bind(estate_bulk_eject, ids, true, boost::bind(LLNotificationsUtil::getSelectedOption, _1, _2))); +} class ListEstateBan : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - const uuid_vec_t& ids = get_focused_list_ids_selected(); - LLNotificationsUtil::add("EstateBanUser", create_args(ids, "EVIL_USER"), LLSD(), boost::bind(estate_bulk_eject, ids, true, boost::bind(LLNotificationsUtil::getSelectedOption, _1, _2))); + confirm_estate_ban(get_focused_list_ids_selected()); return true; } }; +void confirm_estate_kick(const uuid_vec_t& ids) +{ + LLNotificationsUtil::add("EstateKickUser", create_args(ids, "EVIL_USER"), LLSD(), boost::bind(estate_bulk_eject, ids, false, boost::bind(LLNotificationsUtil::getSelectedOption, _1, _2))); +} class ListEstateEject : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - const uuid_vec_t& ids = get_focused_list_ids_selected(); - LLNotificationsUtil::add("EstateKickUser", create_args(ids, "EVIL_USER"), LLSD(), boost::bind(estate_bulk_eject, ids, false, boost::bind(LLNotificationsUtil::getSelectedOption, _1, _2))); + confirm_estate_kick(get_focused_list_ids_selected()); return true; } }; @@ -9395,18 +9470,73 @@ class ListToggleMute : public view_listener_t } }; -LLMediaCtrl* get_focused_media_ctrl() +struct MenuSLURLDict : public LLSingleton { - auto media_ctrl = dynamic_cast(gFocusMgr.getKeyboardFocus()); - llassert(media_ctrl); // This listener only applies to media_ctrls - return media_ctrl; -} + typedef std::function cb; + typedef std::function vcb; + typedef std::map> slurl_menu_map; + slurl_menu_map mEntries; + MenuSLURLDict() + { + // Text Editor menus + LLTextEditor::setIsObjectBlockedCallback(boost::bind(&LLMuteList::isMuted, LLMuteList::getInstance(), _1, _2, 0)); + LLTextEditor::setIsFriendCallback(LLAvatarActions::isFriend); + LLTextEditor::addMenuListeners(boost::bind(&MenuSLURLDict::action, this, _1, _2), boost::bind(&MenuSLURLDict::visible, this, _1, _2)); + + // Add the entries + insert("ShowWebProfile", boost::bind(LLAvatarActions::showProfile, _1, true), boost::bind(can_show_web_profile)); + insert("Pay", LLAvatarActions::pay); + insert("Call", LLAvatarActions::startCall); + insert("Share", LLAvatarActions::share); + insert("AbuseReport", LLFloaterReporter::showFromObject); + insert("InviteToGroup", [](const LLUUID& id) { LLAvatarActions::inviteToGroup(id); }); + insert("BanFromGroup", [](const LLUUID& id) { ban_from_group(uuid_vec_t(1, id)); }); + insert("ShowLog", [](const LLUUID& id) { show_log_browser(id); }); + insert("OfferTeleport", [](const LLUUID& id) { LLAvatarActions::offerTeleport(id); }, [](const LLUUID& id) { return LLAvatarActions::canOfferTeleport(id); }); + insert("RequestTeleport", LLAvatarActions::teleportRequest); + void teleport_to(const LLUUID& id); + insert("TeleportTo", teleport_to, is_nearby); + insert("Focus", LLFloaterAvatarList::setFocusAvatar, is_nearby); + insert("ParcelEject", [](const LLUUID& id) { confirm_eject(uuid_vec_t(1, id)); }, is_nearby); + insert("Freeze", [](const LLUUID& id) { confirm_freeze(uuid_vec_t(1, id)); }, is_nearby); + insert("EstateBan", [](const LLUUID& id) { confirm_estate_ban(uuid_vec_t(1, id)); }, is_nearby); + insert("EstateEject", [](const LLUUID & id) { confirm_estate_kick(uuid_vec_t(1, id)); }, is_nearby); + insert("Mute", LLAvatarActions::toggleBlock, [](const LLUUID& id) { return LLAvatarActions::canBlock(id) && !LLAvatarActions::isBlocked(id); }); + insert("Unmute", LLAvatarActions::toggleBlock, LLAvatarActions::isBlocked); + } + + void insert(const std::string& key, cb callback, vcb vcallback = nullptr) + { + mEntries[key] = std::make_pair(callback, vcallback); + } + + void action(const std::string& cmd, LLUUID id) const + { + auto it = mEntries.find(cmd); + if (it != mEntries.end()) + (*it).second.first(id); + } + bool visible(const std::string& cmd, LLUUID id) const + { + auto it = mEntries.find(cmd); + return it == mEntries.end() || !(*it).second.second || (*it).second.second(id); + } +}; + +class MediaCtrlCopyURL : public view_listener_t +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + get_focused()->onCopyURL(); + return true; + } +}; class MediaCtrlWebInspector : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - get_focused_media_ctrl()->onOpenWebInspector(); + get_focused()->onOpenWebInspector(); return true; } }; @@ -9415,7 +9545,7 @@ class MediaCtrlViewSource : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - get_focused_media_ctrl()->onShowSource(); + get_focused()->onShowSource(); return true; } }; @@ -9727,6 +9857,8 @@ void initialize_menus() addMenu(new VisibleInvFloaterName, "InvFloaterVisible.Name"); addMenu(new VisibleInvFloaterType, "InvFloaterVisible.Type"); + addMenu(new ShowWebFloater, "ShowWebFloater"); + // [RLVa:KB] - Checked: 2010-01-18 (RLVa-1.1.0m) | Added: RLVa-1.1.0m | OK if (rlv_handler_t::isEnabled()) { @@ -9765,6 +9897,8 @@ void initialize_menus() addMenu(new ListStartConference(), "List.StartConference"); addMenu(new ListStartIM(), "List.StartIM"); addMenu(new ListAbuseReport(), "List.AbuseReport"); + addMenu(new ListIsNearby, "List.IsNearby"); + addMenu(new ListTrack, "List.Track"); addMenu(new ListEject(), "List.ParcelEject"); addMenu(new ListFreeze(), "List.Freeze"); addMenu(new ListEstateBan(), "List.EstateBan"); @@ -9773,12 +9907,10 @@ void initialize_menus() add_radar_listeners(); - // Text Editor menus - LLTextEditor::setIsObjectBlockedCallback(boost::bind(&LLMuteList::isMuted, LLMuteList::getInstance(), _1, _2, 0)); - LLTextEditor::setIsFriendCallback(LLAvatarActions::isFriend); - LLTextEditor::addMenuListeners(); + MenuSLURLDict::getInstance(); // Media Ctrl menus + addMenu(new MediaCtrlCopyURL(), "Copy.PageURL"); addMenu(new MediaCtrlWebInspector(), "Open.WebInspector"); addMenu(new MediaCtrlViewSource(), "Open.ViewSource"); diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 72ef3aafe..53047ceee 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -1984,6 +1984,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames) capabilityNames.append("DispatchRegionInfo"); capabilityNames.append("DirectDelivery"); capabilityNames.append("EnvironmentSettings"); + capabilityNames.append("EstateAccess"); capabilityNames.append("EstateChangeInfo"); capabilityNames.append("EventQueueGet"); capabilityNames.append("ExtEnvironment"); @@ -2019,6 +2020,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames) capabilityNames.append("ParcelVoiceInfoRequest"); capabilityNames.append("ProductInfoRequest"); capabilityNames.append("ProvisionVoiceAccountRequest"); + capabilityNames.append("ReadOfflineMsgs"); // Requires to respond reliably: AcceptFriendship, AcceptGroupInvite, DeclineFriendship, DeclineGroupInvite capabilityNames.append("RemoteParcelRequest"); capabilityNames.append("RenderMaterials"); capabilityNames.append("RequestTextureDownload"); diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h index 5e77c8900..7a04528f3 100644 --- a/indra/newview/llviewertexture.h +++ b/indra/newview/llviewertexture.h @@ -603,7 +603,7 @@ private: LLViewerMediaImpl* mMediaImplp ; BOOL mIsPlaying ; - U32 mUpdateVirtualSizeTime ; + U64 mUpdateVirtualSizeTime ; public: static void updateClass() ; diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index 9d19ca427..ebd2376ed 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -120,6 +120,7 @@ void LLViewerTextureList::doPreloadImages() llassert_always(mInitialized) ; llassert_always(mImageList.empty()) ; llassert_always(mUUIDMap.empty()) ; + llassert_always(mUUIDDict.empty()); // Set the "missing asset" image LLViewerFetchedTexture::sMissingAssetImagep = LLViewerTextureManager::getFetchedTextureFromFile("missing_asset.tga", FTT_LOCAL_FILE, MIPMAP_NO, LLViewerFetchedTexture::BOOST_UI); @@ -602,7 +603,7 @@ LLViewerFetchedTexture* LLViewerTextureList::createImage(const LLUUID &image_id, LLViewerFetchedTexture *LLViewerTextureList::findImage(const LLUUID &image_id) { // Singu note: Reworked hotspot - auto& iter = mUUIDDict.find(image_id); + const auto& iter = mUUIDDict.find(image_id); if(iter == mUUIDDict.end()) return NULL; return iter->second; @@ -650,7 +651,7 @@ void LLViewerTextureList::removeImageFromList(LLViewerFetchedTexture *image) << " but doesn't have mInImageList set" << " ref count is " << image->getNumRefs() << LL_ENDL; - auto& iter = mUUIDDict.find(image->getID()); + const auto& iter = mUUIDDict.find(image->getID()); if(iter == mUUIDDict.end()) { LL_INFOS() << "Image " << image->getID() << " is also not in mUUIDMap!" << LL_ENDL ; @@ -692,8 +693,12 @@ void LLViewerTextureList::addImage(LLViewerFetchedTexture *new_image) sNumImages++; addImageToList(new_image); - mUUIDMap.emplace(image_id, new_image); - mUUIDDict.emplace(image_id, new_image); + auto ret_pair = mUUIDMap.emplace(image_id, new_image); + if (!ret_pair.second) + { + ret_pair.first->second = new_image; + } + mUUIDDict.insert_or_assign(image_id, new_image); } diff --git a/indra/newview/llviewertexturelist.h b/indra/newview/llviewertexturelist.h index e69b9ddbc..240a86050 100644 --- a/indra/newview/llviewertexturelist.h +++ b/indra/newview/llviewertexturelist.h @@ -37,6 +37,8 @@ #include #include +#include "absl/container/flat_hash_map.h" + const U32 LL_IMAGE_REZ_LOSSLESS_CUTOFF = 128; const BOOL MIPMAP_YES = TRUE; @@ -188,8 +190,8 @@ public: private: typedef std::map< LLUUID, LLPointer > uuid_map_t; uuid_map_t mUUIDMap; - typedef std::unordered_map< LLUUID, LLPointer* > uuid_dict_t; - uuid_map_t mUUIDDict; + typedef absl::flat_hash_map< LLUUID, LLViewerFetchedTexture* > uuid_dict_t; + uuid_dict_t mUUIDDict; LLUUID mLastUpdateUUID; LLUUID mLastFetchUUID; diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index dc91b315d..d42592976 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -8628,12 +8628,16 @@ BOOL LLVOAvatar::isFullyLoaded() const bool LLVOAvatar::isTooComplex() const { - static const LLCachedControl always_render_friends("AlwaysRenderFriends", true); + static const LLCachedControl always_render_friends("AlwaysRenderFriends", 0); bool too_complex; if (isSelf() || (always_render_friends && LLAvatarTracker::instance().isBuddy(getID()))) { too_complex = false; } + else if (always_render_friends == 2) + { + too_complex = true; + } else { // Determine if visually muted or not diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index 8eec26c6f..dccd0242c 100644 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -3564,6 +3564,11 @@ void LLVivoxVoiceClient::participantUpdatedEvent( */ LLVoiceChannel* voice_cnl = LLVoiceChannel::getCurrentVoiceChannel(); + // Singu Note: This block is different so we also update the active speaker list. + // also initialize voice moderate_mode depend on Agent's participant. See EXT-6937. + // *TODO: remove once a way to request the current voice channel moderation mode is implemented. + bool moderate = gAgentID == participant->mAvatarID; + // ignore session ID of local chat if (voice_cnl && voice_cnl->getSessionID().notNull()) { @@ -3576,14 +3581,20 @@ void LLVivoxVoiceClient::participantUpdatedEvent( { speaker_manager->update(true); - // also initialize voice moderate_mode depend on Agent's participant. See EXT-6937. - // *TODO: remove once a way to request the current voice channel moderation mode is implemented. - if (gAgent.getID() == participant->mAvatarID) + if (moderate) { speaker_manager->initVoiceModerateMode(); } } } + else if (voice_cnl) // Local + { + LLLocalSpeakerMgr::instance().update(true); + } + // Always update active speakers + auto& inst(LLActiveSpeakerMgr::instance()); + inst.update(true); + if (moderate) inst.initVoiceModerateMode(); } else { diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index c02c090e7..c4af5dc18 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -4568,7 +4568,7 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons } } - U32 frame = LLFrameTimer::getFrameCount(); + U64 frame = LLFrameTimer::getFrameCount(); if (copy) { copyVolumeFaces(volume); diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index 7fe018940..b76620d24 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -61,7 +61,7 @@ enum LLVolumeInterfaceType class LLRiggedVolume : public LLVolume { - U32 mFrame; + U64 mFrame; public: LLRiggedVolume(const LLVolumeParams& params) : LLVolume(params, 0.f), mFrame(-1) diff --git a/indra/newview/skins/apollo/keywords.ini b/indra/newview/skins/apollo/keywords.ini index 26c994488..33130fc75 100644 --- a/indra/newview/skins/apollo/keywords.ini +++ b/indra/newview/skins/apollo/keywords.ini @@ -54,6 +54,9 @@ http_response http_response(key request_id, integer status, list metad http_request http_request(key id, string method, string body):Triggered when task receives an http request against a public URL transaction_result transaction_result(key id, integer success, string data): Triggered when currency is given to task path_update path_update(integer type, list reserved):Triggered when the state of a pathfinder character changes. Note; "list reserved" is not currently used +experience_permissions experience_permissions(key agent): Triggered when agent has approved an experience permissions request. This may be through interaction with the experience permission dialog or the experience profile, or automatically if the agent has previously approved the experience. +experience_permissions_denied experience_permissions_denied(key agent, integer reason): Triggered when agent has denied experience permission. reason is the reason for denial; one of the Experience Tools XP_ERROR_* errors flags. + # integer constants [word .679, .503, .996] @@ -102,6 +105,23 @@ PERMISSION_TELEPORT Passed to llRequestPermissions library function to reque SCRIPT_PERMISSION_SILENT_ESTATE_MANAGEMENT Passed to llRequestPermissions library function to request permission to silently modify estate access lists PERMISSION_OVERRIDE_ANIMATIONS Passed to llRequestPermissions library function to request permission to override animations on agent PERMISSION_RETURN_OBJECTS Passed to llRequestPermissions library function to request permission to return objects +XP_ERROR_NONE No error was detected. +XP_ERROR_THROTTLED The call failed due to too many recent calls. +XP_ERROR_EXPERIENCES_DISABLED The region currently has experiences disabled. +XP_ERROR_INVALID_PARAMETERS One of the string arguments was too big to fit in the key-value store. +XP_ERROR_NOT_PERMITTED This experience is not allowed to run on the current region. +XP_ERROR_NO_EXPERIENCE This script is not associated with an experience. +XP_ERROR_NOT_FOUND The sim was unable to verify the validity of the experience. Retrying after a short wait is advised. +XP_ERROR_INVALID_EXPERIENCE The script is associated with an experience that no longer exists. +XP_ERROR_EXPERIENCE_DISABLED The experience owner has temporarily disabled the experience. +XP_ERROR_EXPERIENCE_SUSPENDED The experience has been suspended by Linden Lab customer support. +XP_ERROR_UNKNOWN_ERROR An unknown error not covered by any of the other predetermined error states. +XP_ERROR_QUOTA_EXCEEDED An attempt to write data to the key-value store failed due to the data quota being met. +XP_ERROR_STORE_DISABLED The key-value store is currently disabled on this region. +XP_ERROR_STORAGE_EXCEPTION Unable to communicate with the key-value store. +XP_ERROR_KEY_NOT_FOUND The requested key does not exist. +XP_ERROR_RETRY_UPDATE A checked update failed due to an out of date request. +XP_ERROR_MATURITY_EXCEEDED The content rating of the experience exceeds that of the region. DEBUG_CHANNEL Chat channel reserved for debug and error messages from scripts PUBLIC_CHANNEL Chat channel that broadcasts to all nearby users @@ -919,6 +939,25 @@ TEXTURE_TRANSPARENT UUID for the "White - Transparent" texture URL_REQUEST_GRANTED Used with http_request when a public URL is successfully granted URL_REQUEST_DENIED Used with http_request when a public URL is not available +XP_ERROR_NONE No error was detected +XP_ERROR_THROTTLED The call failed due to too many recent calls. +XP_ERROR_EXPERIENCES_DISABLED The region currently has experiences disabled. +XP_ERROR_INVALID_PARAMETERS One of the string arguments was too big to fit in the key-value store. +XP_ERROR_NOT_PERMITTED This experience is not allowed to run on the current region. +XP_ERROR_NO_EXPERIENCE This script is not associated with an experience. +XP_ERROR_NOT_FOUND The sim was unable to verify the validity of the experience. Retrying after a short wait is advised. +XP_ERROR_INVALID_EXPERIENCE The script is associated with an experience that no longer exists. +XP_ERROR_EXPERIENCE_DISABLED The experience owner has temporarily disabled the experience. +XP_ERROR_EXPERIENCE_SUSPENDED The experience has been suspended by Linden Customer Support. +XP_ERROR_QUOTA_EXCEEDED An attempted write data to the key-value store failed due to the data quota being met. +XP_ERROR_STORE_DISABLED The key-value store is currently disabled on this region. +XP_ERROR_STORAGE_EXCEPTION Unable to communicate with the key-value store. +XP_ERROR_KEY_NOT_FOUND The requested key does not exist. +XP_ERROR_RETRY_UPDATE A checked update failed due to an out of date request. +XP_ERROR_MATURITY_EXCEEDED The request failed due to agent content preferences. +XP_ERROR_UNKNOWN_ERROR Other unknown error. + + # float constants [word .679, .503, .996] PI 3.1415926535897932384626433832795 diff --git a/indra/newview/skins/default/textures/icn_toolbar_marketplace.tga b/indra/newview/skins/default/textures/icn_toolbar_marketplace.tga new file mode 100644 index 000000000..49e5d11a2 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_marketplace.tga differ diff --git a/indra/newview/skins/default/textures/icn_toolbar_received_items.tga b/indra/newview/skins/default/textures/icn_toolbar_received_items.tga new file mode 100644 index 000000000..49e5d11a2 Binary files /dev/null and b/indra/newview/skins/default/textures/icn_toolbar_received_items.tga differ diff --git a/indra/newview/skins/default/xui/de/floater_active_speakers.xml b/indra/newview/skins/default/xui/de/floater_active_speakers.xml index e562e44fb..0e63e4c87 100644 --- a/indra/newview/skins/default/xui/de/floater_active_speakers.xml +++ b/indra/newview/skins/default/xui/de/floater_active_speakers.xml @@ -3,11 +3,11 @@ - + - + + + diff --git a/indra/newview/skins/default/xui/en-us/floater_instant_message.xml b/indra/newview/skins/default/xui/en-us/floater_instant_message.xml index 331ee9b8a..356a41861 100644 --- a/indra/newview/skins/default/xui/en-us/floater_instant_message.xml +++ b/indra/newview/skins/default/xui/en-us/floater_instant_message.xml @@ -16,6 +16,7 @@ + diff --git a/indra/newview/skins/default/xui/en-us/floater_instant_message_concisebuttons.xml b/indra/newview/skins/default/xui/en-us/floater_instant_message_concisebuttons.xml index 6bfe25215..a2590a7ed 100644 --- a/indra/newview/skins/default/xui/en-us/floater_instant_message_concisebuttons.xml +++ b/indra/newview/skins/default/xui/en-us/floater_instant_message_concisebuttons.xml @@ -20,6 +20,7 @@ + diff --git a/indra/newview/skins/default/xui/en-us/floater_instant_message_group.xml b/indra/newview/skins/default/xui/en-us/floater_instant_message_group.xml index a9cfeeb46..66d694f1a 100644 --- a/indra/newview/skins/default/xui/en-us/floater_instant_message_group.xml +++ b/indra/newview/skins/default/xui/en-us/floater_instant_message_group.xml @@ -17,7 +17,7 @@ - + - + + width="181" /> + font="SansSerifSmall" h_pad="0" halign="left" height="16" left_delta="185" + mouse_opaque="true" name="online_yes" v_pad="0" width="136"> Currently Online + font="SansSerifSmall" h_pad="0" halign="left" height="16" left_delta="0" + mouse_opaque="true" name="label" v_pad="0" width="136"> Born: + width="137" /> + font="SansSerifSmall" h_pad="0" halign="left" height="16" left_delta="0" + mouse_opaque="true" name="label2" v_pad="0" width="136"> Account: - + + follows="left|top" font="SansSerifSmall" height="48" left_delta="0" + mouse_opaque="true" name="acct" width="136" /> + v_pad="0" width="135"> Partner: @@ -399,12 +399,17 @@ + + + @@ -412,6 +417,11 @@ + + +