diff --git a/autobuild.xml b/autobuild.xml
index 274dde845..78e8aa34f 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -1351,92 +1351,6 @@
version
1.5.3
- jsoncpp
-
libhunspell
copyright
@@ -2013,6 +1927,38 @@
version
7.11.1.297294
+ modernjson
+
+ copyright
+ Copyright (c) 2013-2018 Niels Lohmann
+ description
+ JSON for Modern C++
+ license
+ MIT
+ license_file
+ LICENSES/modernjson.txt
+ name
+ modernjson
+ platforms
+
+ common
+
+ archive
+
+ hash
+ 6f11eca7e2a6ca61f9217e949a64f026
+ hash_algorithm
+ md5
+ url
+ https://depot.alchemyviewer.org/pub/common/lib/modernjson-3.2.0-common-201809210551.tar.bz2
+
+ name
+ common
+
+
+ version
+ 3.2.0
+
nvapi
copyright
@@ -2476,7 +2422,7 @@
hash_algorithm
md5
url
- https://bitbucket.org/alchemyviewer/publiclibs-darwin/downloads/uriparser-0.8.4-darwin-201511221948.tar.bz2
+ https://depot.alchemyviewer.org/pub/darwin/lib/uriparser-0.8.4-darwin-201511221948.tar.bz2
name
darwin
@@ -2498,11 +2444,11 @@
archive
hash
- 69224d9285e5a26fc7a9aca5d3da7543
+ cf21d9f7ed7949d2230413e8a391fb73
hash_algorithm
md5
url
- http://depot.alchemyviewer.org/pub/linux64/lib-trusty/uriparser-0.8.4-linux64-201603240044.tar.bz2
+ https://depot.alchemyviewer.org/pub/linux64/lib-xenial/uriparser-0.8.4-linux64-201609241428.tar.bz2
name
linux64
@@ -2512,11 +2458,11 @@
archive
hash
- f9f82fbd29751a969e9ab55a1f33ac7b
+ 89f3fc7f3fe396439d306f099d1a12d3
hash_algorithm
md5
url
- http://depot.alchemyviewer.org/pub/windows/lib-vc14/uriparser-0.8.4-windows-201601151009.tar.bz2
+ https://depot.alchemyviewer.org/pub/windows/lib-vc141/uriparser-0.8.4-windows-201703090606.tar.bz2
name
windows
diff --git a/indra/CMakeLists.txt b/indra/CMakeLists.txt
index 59735a520..b480c96b3 100644
--- a/indra/CMakeLists.txt
+++ b/indra/CMakeLists.txt
@@ -19,6 +19,9 @@ set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
include(Variables)
include(BuildVersion)
+set(CMAKE_CXX_STANDARD 14)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+
if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING
"Build type. One of: Debug Release RelWithDebInfo" FORCE)
@@ -58,5 +61,8 @@ add_subdirectory(${LIBS_OPEN_PREFIX}plugins)
add_subdirectory(${VIEWER_PREFIX}newview/statemachine)
add_subdirectory(${VIEWER_PREFIX}newview)
-add_dependencies(viewer singularity-bin)
+add_dependencies(viewer ${VIEWER_BRANDING_ID}-bin)
+if (WINDOWS)
+ set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${VIEWER_BRANDING_ID}-bin)
+endif (WINDOWS)
diff --git a/indra/cmake/00-Common.cmake b/indra/cmake/00-Common.cmake
index 4e1e6cb49..e9868cfea 100644
--- a/indra/cmake/00-Common.cmake
+++ b/indra/cmake/00-Common.cmake
@@ -7,7 +7,6 @@ set(${CMAKE_CURRENT_LIST_FILE}_INCLUDED "YES")
include(Variables)
-
# Portable compilation flags.
set(CMAKE_CXX_FLAGS_DEBUG "-D_DEBUG -DLL_DEBUG=1")
@@ -31,14 +30,11 @@ if(NON_RELEASE_CRASH_REPORTING)
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DLL_SEND_CRASH_REPORTS=1")
endif()
-
# Don't bother with a MinSizeRel build.
-
set(CMAKE_CONFIGURATION_TYPES "RelWithDebInfo;Release;Debug" CACHE STRING
"Supported build types." FORCE)
# Platform-specific compilation flags.
-
if (WINDOWS)
# Don't build DLLs.
set(BUILD_SHARED_LIBS OFF)
@@ -88,6 +84,7 @@ if (WINDOWS)
/DNOMINMAX
/DUNICODE
/D_UNICODE
+ /DBOOST_CONFIG_SUPPRESS_OUTDATED_MESSAGE
/GS
/TP
/W3
@@ -111,7 +108,7 @@ if (WINDOWS)
endif (USE_LTO)
if (WORD_SIZE EQUAL 32)
- add_compile_options(/arch:SSE2)
+ add_compile_options(/arch:SSE3)
endif (WORD_SIZE EQUAL 32)
if (NOT DISABLE_FATAL_WARNINGS)
@@ -128,21 +125,24 @@ set (GCC_EXTRA_OPTIMIZATIONS "-ffast-math")
if (LINUX)
set(CMAKE_SKIP_RPATH TRUE)
+ add_compile_options(
+ -fvisibility=hidden
+ -fexceptions
+ -fno-math-errno
+ -fno-strict-aliasing
+ -fsigned-char
+ -g
+ -pthread
+ )
+
add_definitions(
- -DLL_LINUX=1
- -DAPPID=secondlife
- -D_REENTRANT
- -fexceptions
- -fno-math-errno
- -fno-strict-aliasing
- -fsigned-char
- -fvisibility=hidden
- -g
- -pthread
- )
+ -DLL_LINUX=1
+ -DAPPID=secondlife
+ -D_REENTRANT
+ )
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99")
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++14")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2")
@@ -213,23 +213,23 @@ if (LINUX)
if (NOT STANDALONE)
set(MARCH_FLAG " -march=pentium4")
endif (NOT STANDALONE)
- set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}${MARCH_FLAG} -fno-inline -msse2")
- set(CMAKE_C_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}${MARCH_FLAG} -fno-inline -msse2")
- set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}${MARCH_FLAG} -mfpmath=sse,387 -msse2 ${GCC_EXTRA_OPTIMIZATIONS}")
- set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}${MARCH_FLAG} -mfpmath=sse,387 -msse2 ${GCC_EXTRA_OPTIMIZATIONS}")
- set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}${MARCH_FLAG} -mfpmath=sse,387 -msse2 ${GCC_EXTRA_OPTIMIZATIONS}")
- set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}${MARCH_FLAG} -mfpmath=sse,387 -msse2 ${GCC_EXTRA_OPTIMIZATIONS}")
+ set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}${MARCH_FLAG} -fno-inline -msse3")
+ set(CMAKE_C_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}${MARCH_FLAG} -fno-inline -msse3")
+ set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}${MARCH_FLAG} -mfpmath=sse,387 -msse3 ${GCC_EXTRA_OPTIMIZATIONS}")
+ set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}${MARCH_FLAG} -mfpmath=sse,387 -msse3 ${GCC_EXTRA_OPTIMIZATIONS}")
+ set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}${MARCH_FLAG} -mfpmath=sse,387 -msse3 ${GCC_EXTRA_OPTIMIZATIONS}")
+ set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}${MARCH_FLAG} -mfpmath=sse,387 -msse3 ${GCC_EXTRA_OPTIMIZATIONS}")
endif (${ARCH} STREQUAL "x86_64")
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
- set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}${MARCH_FLAG} -fno-inline -msse2")
- set(CMAKE_C_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}${MARCH_FLAG} -fno-inline -msse2")
- set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}${MARCH_FLAG} -msse2")
- set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}${MARCH_FLAG} -msse2")
- set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}${MARCH_FLAG} -msse2")
- set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}${MARCH_FLAG} -msse2")
+ set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}${MARCH_FLAG} -fno-inline -msse3")
+ set(CMAKE_C_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}${MARCH_FLAG} -fno-inline -msse3")
+ set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}${MARCH_FLAG} -msse3")
+ set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}${MARCH_FLAG} -msse3")
+ set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}${MARCH_FLAG} -msse3")
+ set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}${MARCH_FLAG} -msse3")
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel")
if (NOT STANDALONE)
- set(MARCH_FLAG " -axsse4.1 -msse2")
+ set(MARCH_FLAG " -axsse4.1 -msse3")
endif (NOT STANDALONE)
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}${MARCH_FLAG} -fno-inline-functions")
diff --git a/indra/cmake/CMakeLists.txt b/indra/cmake/CMakeLists.txt
index 7c8e616d6..cacb7fd05 100644
--- a/indra/cmake/CMakeLists.txt
+++ b/indra/cmake/CMakeLists.txt
@@ -36,10 +36,10 @@ set(cmake_SOURCE_FILES
FindGoogleBreakpad.cmake
FindGooglePerfTools.cmake
FindHunSpell.cmake
- FindJsonCpp.cmake
FindNDOF.cmake
FindOpenJPEG.cmake
FindTut.cmake
+ FindURIPARSER.cmake
FindXmlRpcEpi.cmake
FreeType.cmake
GLOD.cmake
@@ -50,7 +50,7 @@ set(cmake_SOURCE_FILES
GooglePerfTools.cmake
Hunspell.cmake
JPEG.cmake
- JsonCpp.cmake
+ Json.cmake
LLAddBuildTest.cmake
LLAppearance.cmake
LLAudio.cmake
@@ -65,7 +65,6 @@ set(cmake_SOURCE_FILES
LLPlugin.cmake
LLPrimitive.cmake
LLPhysicsExtensions.cmake
- LLSharedLibs.cmake
LLRender.cmake
LLSharedLibs.cmake
LLUI.cmake
@@ -93,6 +92,7 @@ set(cmake_SOURCE_FILES
Tut.cmake
UI.cmake
UnixInstall.cmake
+ URIPARSER.cmake
Variables.cmake
ViewerMiscLibs.cmake
WinManifest.cmake
diff --git a/indra/cmake/FindJsonCpp.cmake b/indra/cmake/FindJsonCpp.cmake
deleted file mode 100644
index a48c97396..000000000
--- a/indra/cmake/FindJsonCpp.cmake
+++ /dev/null
@@ -1,39 +0,0 @@
-# -*- cmake -*-
-
-# - Find JSONCpp
-# Find the JSONCpp includes and library
-# This module defines
-# JSONCPP_FOUND, System has libjsoncpp.
-# JSONCPP_INCLUDE_DIRS - The libjsoncpp include directories.
-# JSONCPP_LIBRARIES - The libraries needed to use libjsoncpp.
-# JSONCPP_DEFINITIONS - Compiler switches required for using libjsoncpp.
-
-FIND_PACKAGE(PkgConfig)
-PKG_CHECK_MODULES(PC_JSONCPP jsoncpp)
-SET(JSONCPP_DEFINITIONS ${PC_JSONCPP_CFLAGS_OTHER})
-
-FIND_PATH(JSONCPP_INCLUDE_DIR json/reader.h
- HINTS ${PC_JSONCPP_INCLUDE_DIR} ${PC_JSONCPP_INCLUDE_DIRS}
- PATH_SUFFIXES jsoncpp)
-
-# Get the GCC compiler version
-EXEC_PROGRAM(${CMAKE_CXX_COMPILER}
- ARGS ${CMAKE_CXX_COMPILER_ARG1} -dumpversion
- OUTPUT_VARIABLE _gcc_COMPILER_VERSION
- OUTPUT_STRIP_TRAILING_WHITESPACE
- )
-
-# Try to find a library that was compiled with the same compiler version as we currently use.
-FIND_LIBRARY(JSONCPP_LIBRARY
- NAMES libjson_linux-gcc-${_gcc_COMPILER_VERSION}_libmt.so libjsoncpp.so
- HINTS ${PC_JSONCPP_LIBDIR} ${PC_JSONCPP_LIBRARY_DIRS}
- PATHS /usr/lib /usr/local/lib)
-
-SET(JSONCPP_LIBRARIES ${JSONCPP_LIBRARY})
-SET(JSONCPP_INCLUDE_DIRS ${JSONCPP_INCLUDE_DIR})
-
-include(FindPackageHandleStandardArgs)
-FIND_PACKAGE_HANDLE_STANDARD_ARGS(JSONCPP DEFAULT_MSG
- JSONCPP_LIBRARY JSONCPP_INCLUDE_DIR)
-
-MARK_AS_ADVANCED(JSONCPP_LIBRARY JSONCPP_INCLUDE_DIR)
diff --git a/indra/cmake/FindURIPARSER.cmake b/indra/cmake/FindURIPARSER.cmake
new file mode 100644
index 000000000..05f2d1737
--- /dev/null
+++ b/indra/cmake/FindURIPARSER.cmake
@@ -0,0 +1,46 @@
+# -*- cmake -*-
+
+# - Find uriparser
+# Find the URIPARSER includes and library
+# This module defines
+# URIPARSER_INCLUDE_DIRS, where to find uriparser.h, etc.
+# URIPARSER_LIBRARY, the libraries needed to use uriparser.
+# URIPARSER_FOUND, If false, do not try to use uriparser.
+#
+# This FindURIPARSER is about 43 times as fast the one provided with cmake (2.8.x),
+# because it doesn't look up the version of uriparser, resulting in a dramatic
+# speed up for configure (from 4 minutes 22 seconds to 6 seconds).
+#
+# Note: Since this file is only used for standalone, the windows
+# specific parts were left out.
+
+FIND_PATH(URIPARSER_INCLUDE_DIR uriparser/Uri.h
+ NO_SYSTEM_ENVIRONMENT_PATH
+ )
+
+FIND_LIBRARY(URIPARSER_LIBRARY uriparser)
+
+if (URIPARSER_LIBRARY AND URIPARSER_INCLUDE_DIR)
+ SET(URIPARSER_INCLUDE_DIRS ${URIPARSER_INCLUDE_DIR})
+ SET(URIPARSER_LIBRARY ${URIPARSER_LIBRARY})
+ SET(URIPARSER_FOUND "YES")
+else (URIPARSER_LIBRARY AND URIPARSER_INCLUDE_DIR)
+ SET(URIPARSER_FOUND "NO")
+endif (URIPARSER_LIBRARY AND URIPARSER_INCLUDE_DIR)
+
+if (URIPARSER_FOUND)
+ if (NOT URIPARSER_FIND_QUIETLY)
+ message(STATUS "Found URIPARSER: ${URIPARSER_LIBRARY}")
+ SET(URIPARSER_FIND_QUIETLY TRUE)
+ endif (NOT URIPARSER_FIND_QUIETLY)
+else (URIPARSER_FOUND)
+ if (URIPARSER_FIND_REQUIRED)
+ message(FATAL_ERROR "Could not find URIPARSER library")
+ endif (URIPARSER_FIND_REQUIRED)
+endif (URIPARSER_FOUND)
+
+mark_as_advanced(
+ URIPARSER_LIBRARY
+ URIPARSER_INCLUDE_DIR
+ )
+
diff --git a/indra/cmake/Json.cmake b/indra/cmake/Json.cmake
new file mode 100644
index 000000000..5c9837047
--- /dev/null
+++ b/indra/cmake/Json.cmake
@@ -0,0 +1,6 @@
+# -*- cmake -*-
+
+include(Prebuilt)
+
+use_prebuilt_binary(modernjson)
+set(JSON_INCLUDE_DIR "${LIBS_PREBUILT_DIR}/include")
diff --git a/indra/cmake/JsonCpp.cmake b/indra/cmake/JsonCpp.cmake
deleted file mode 100644
index 4bde364ce..000000000
--- a/indra/cmake/JsonCpp.cmake
+++ /dev/null
@@ -1,22 +0,0 @@
-# -*- cmake -*-
-
-include(Prebuilt)
-
-set(JSONCPP_FIND_QUIETLY OFF)
-set(JSONCPP_FIND_REQUIRED ON)
-
-if (STANDALONE)
- include(FindJsonCpp)
-else (STANDALONE)
- use_prebuilt_binary(jsoncpp)
- if (WINDOWS)
- set(JSONCPP_LIBRARIES
- debug jsoncppd.lib
- optimized jsoncpp.lib)
- elseif (DARWIN)
- set(JSONCPP_LIBRARIES json_linux-gcc-4.0.1_libmt)
- elseif (LINUX)
- set(JSONCPP_LIBRARIES jsoncpp)
- endif (WINDOWS)
- set(JSONCPP_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/)
-endif (STANDALONE)
diff --git a/indra/cmake/URIPARSER.cmake b/indra/cmake/URIPARSER.cmake
new file mode 100644
index 000000000..47c3ccd37
--- /dev/null
+++ b/indra/cmake/URIPARSER.cmake
@@ -0,0 +1,20 @@
+# -*- cmake -*-
+
+set(URIPARSER_FIND_QUIETLY ON)
+set(URIPARSER_FIND_REQUIRED ON)
+
+include(Prebuilt)
+
+if (USESYSTEMLIBS)
+ include(FindURIPARSER)
+else (USESYSTEMLIBS)
+ use_prebuilt_binary(uriparser)
+ if (WINDOWS)
+ set(URIPARSER_LIBRARY
+ debug uriparserd
+ optimized uriparser)
+ elseif (DARWIN OR LINUX)
+ set(URIPARSER_LIBRARY uriparser)
+ endif (WINDOWS)
+ set(URIPARSER_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include/uriparser)
+endif (USESYSTEMLIBS)
diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt
index 80eeab0d4..b59485a06 100644
--- a/indra/llcommon/CMakeLists.txt
+++ b/indra/llcommon/CMakeLists.txt
@@ -10,21 +10,23 @@ include(Linking)
include(Boost)
include(OpenSSL)
include(LLSharedLibs)
+include(Json)
include(GoogleBreakpad)
include(Copy3rdPartyLibs)
include(ZLIB)
+include(URIPARSER)
include_directories(
${EXPAT_INCLUDE_DIRS}
${LLCOMMON_INCLUDE_DIRS}
${OPENSSL_INCLUDE_DIRS}
+ ${JSON_INCLUDE_DIR}
${ZLIB_INCLUDE_DIRS}
${BREAKPAD_INCLUDE_DIRECTORIES}
)
set(llcommon_SOURCE_FILES
aialert.cpp
- aifile.cpp
aiframetimer.cpp
aisyncclient.cpp
aithreadid.cpp
@@ -85,6 +87,7 @@ set(llcommon_SOURCE_FILES
llrun.cpp
llscopedvolatileaprpool.h
llsd.cpp
+ llsdjson.cpp
llsdparam.cpp
llsdserialize.cpp
llsdserialize_xml.cpp
@@ -101,6 +104,7 @@ set(llcommon_SOURCE_FILES
llthreadsafequeue.cpp
lltimer.cpp
lluri.cpp
+ lluriparser.cpp
lluuid.cpp
llworkerthread.cpp
metaclass.cpp
@@ -114,7 +118,6 @@ set(llcommon_HEADER_FILES
CMakeLists.txt
aialert.h
- aifile.h
aiframetimer.h
airecursive.h
aisyncclient.h
@@ -210,6 +213,7 @@ set(llcommon_HEADER_FILES
llrun.h
llsafehandle.h
llsd.h
+ llsdjson.h
llsdparam.h
llsdserialize.h
llsdserialize_xml.h
@@ -238,6 +242,7 @@ set(llcommon_HEADER_FILES
llunittype.h
lltypeinfolookup.h
lluri.h
+ lluriparser.h
lluuid.h
llwin32headers.h
llwin32headerslean.h
@@ -296,6 +301,7 @@ target_link_libraries(
${Boost_THREAD_LIBRARY}
${Boost_SYSTEM_LIBRARY}
${CORESERVICES_LIBRARY}
+ ${URIPARSER_LIBRARY}
)
if (DARWIN)
diff --git a/indra/llcommon/aifile.cpp b/indra/llcommon/aifile.cpp
deleted file mode 100644
index cd2ade77a..000000000
--- a/indra/llcommon/aifile.cpp
+++ /dev/null
@@ -1,119 +0,0 @@
-/**
- * @file aifile.cpp
- * @brief POSIX file operations that throw on error.
- *
- * Copyright (c) 2013, Aleric Inglewood.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- * 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.
- *
- * CHANGELOG
- * and additional copyright holders.
- *
- * 03/11/2013
- * Initial version, written by Aleric Inglewood @ SL
- */
-
-#include "linden_common.h"
-#include "aifile.h"
-#include "aialert.h"
-
-#if LL_WINDOWS
-#include
-#include // Windows errno
-#else
-#include
-#endif
-
-AIFile::AIFile(std::string const& filename, char const* accessmode)
-{
- mFp = AIFile::fopen(filename, accessmode);
-}
-
-AIFile::~AIFile()
-{
- AIFile::close(mFp);
-}
-
-// Like THROW_MALERTE but appends "LLFile::strerr(errn) << " (" << errn << ')'" as argument to replace [ERROR].
-#define THROW_ERROR(...) \
- do { \
- int errn = errno; \
- std::ostringstream error; \
- error << LLFile::strerr(errn) << " (" << errn << ')'; \
- THROW_MALERT_CLASS(AIAlert::ErrorCode, errn, __VA_ARGS__ ("[ERROR]", error.str())); \
- } while(0)
-
-//static
-void AIFile::mkdir(std::string const& dirname, int perms)
-{
- int rc = LLFile::mkdir_nowarn(dirname, perms);
- if (rc < 0 && errno != EEXIST)
- {
- THROW_ERROR("AIFile_mkdir_Failed_to_create_DIRNAME", AIArgs("[DIRNAME]", dirname));
- }
-}
-
-//static
-void AIFile::rmdir(std::string const& dirname)
-{
- int rc = LLFile::rmdir_nowarn(dirname);
- if (rc < 0 && errno != ENOENT)
- {
- THROW_ERROR("AIFile_rmdir_Failed_to_remove_DIRNAME", AIArgs("[DIRNAME]", dirname));
- }
-}
-
-//static
-LLFILE* AIFile::fopen(std::string const& filename, const char* mode)
-{
- LLFILE* fp = LLFile::fopen(filename, mode);
- if (!fp)
- {
- THROW_ERROR("AIFile_fopen_Failed_to_open_FILENAME", AIArgs("[FILENAME]", filename));
- }
- return fp;
-}
-
-//static
-void AIFile::close(LLFILE* file)
-{
- if (LLFile::close(file) < 0)
- {
- THROW_ERROR("AIFile_close_Failed_to_close_file", AIArgs);
- }
-}
-
-//static
-void AIFile::remove(std::string const& filename)
-{
- int rc = LLFile::remove_nowarn(filename);
- if (rc < 0 && errno != ENOENT)
- {
- THROW_ERROR("AIFile_remove_Failed_to_remove_FILENAME", AIArgs("[FILENAME]", filename));
- }
-}
-
-//static
-void AIFile::rename(std::string const& filename, std::string const& newname)
-{
- if (LLFile::rename_nowarn(filename, newname) < 0)
- {
- THROW_ERROR("AIFile_rename_Failed_to_rename_FILE_to_NEWFILE", AIArgs("[FILE]", filename)("[NEWFILE]", newname));
- }
-}
-
diff --git a/indra/llcommon/aifile.h b/indra/llcommon/aifile.h
deleted file mode 100644
index 1b110496a..000000000
--- a/indra/llcommon/aifile.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/**
- * @file aifile.h
- * @brief Declaration of AIFile.
- *
- * Copyright (c) 2013, Aleric Inglewood.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- *
- * 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.
- *
- * CHANGELOG
- * and additional copyright holders.
- *
- * 02/11/2013
- * Initial version, written by Aleric Inglewood @ SL
- */
-
-#ifndef AIFILE_H
-#define AIFILE_H
-
-#include "llfile.h"
-
-// As LLFile, but throws AIAlert instead of printing a warning.
-class LL_COMMON_API AIFile
-{
- private:
- LLFILE* mFp;
-
- public:
- // Scoped file (exception safe). Throws AIAlertCode with errno on failure.
- AIFile(std::string const& filename, char const* accessmode);
- ~AIFile();
-
- operator LLFILE* () const { return mFp; }
-
- // All these functions take UTF8 path/filenames.
- static LLFILE* fopen(std::string const& filename, char const* accessmode);
- static void close(LLFILE* file);
-
- static void mkdir(std::string const& dirname, int perms = 0700); // Does NOT throw when dirname already exists.
- static void rmdir(std::string const& dirname); // Does NOT throw when dirname does not exist.
- static void remove(std::string const& filename); // Does NOT throw when filename does not exist.
- static void rename(std::string const& filename, std::string const& newname);
-};
-
-#endif // AIFILE_H
diff --git a/indra/llcommon/indra_constants.h b/indra/llcommon/indra_constants.h
index d600936d8..9936dfd33 100644
--- a/indra/llcommon/indra_constants.h
+++ b/indra/llcommon/indra_constants.h
@@ -131,19 +131,6 @@ const U32 DEFAULT_CGI_SERVICES_PORT = 12045;
// on a single host for map tile generation. JC
const U32 DEFAULT_MAPSERVER_PORT = 12124;
-const char LAND_LAYER_CODE = 'L';
-const char WATER_LAYER_CODE = 'W';
-const char WIND_LAYER_CODE = '7';
-const char CLOUD_LAYER_CODE = '8';
-
-// Aurora Sim
-// Extended land layer for Aurora Sim
-const char AURORA_LAND_LAYER_CODE = 'M';
-const char AURORA_WATER_LAYER_CODE = 'X';
-const char AURORA_WIND_LAYER_CODE = '9';
-const char AURORA_CLOUD_LAYER_CODE = ':';
-// Aurora Sim
-
enum ETerrainBrushType
{
// the valid brush numbers cannot be reordered, because they
diff --git a/indra/llcommon/llassettype.cpp b/indra/llcommon/llassettype.cpp
index 5b22d5bab..66602f4e7 100644
--- a/indra/llcommon/llassettype.cpp
+++ b/indra/llcommon/llassettype.cpp
@@ -101,6 +101,9 @@ LLAssetDictionary::LLAssetDictionary()
addEntry(LLAssetType::AT_OUTFIT, new AssetEntry("OUTFIT", "outfit", "outfit", false, false, false));
addEntry(LLAssetType::AT_MY_OUTFITS, new AssetEntry("MY_OUTFITS", "my_otfts", "my outfits", false, false, false));
addEntry(LLAssetType::AT_MESH, new AssetEntry("MESH", "mesh", "mesh", false, true, true));
+ addEntry(LLAssetType::AT_SETTINGS, new AssetEntry("SETTINGS", "settings", "settings blob", true, true, true));
+
+ addEntry(LLAssetType::AT_UNKNOWN, new AssetEntry("UNKNOWN", "invalid", NULL, false, false, false));
addEntry(LLAssetType::AT_NONE, new AssetEntry("NONE", "-1", NULL, false, false, false));
};
diff --git a/indra/llcommon/llassettype.h b/indra/llcommon/llassettype.h
index e6fee54ca..9435eeb2b 100644
--- a/indra/llcommon/llassettype.h
+++ b/indra/llcommon/llassettype.h
@@ -122,6 +122,9 @@ public:
AT_LINK_FOLDER = 25,
// Inventory folder link
+
+ AT_MARKETPLACE_FOLDER = 26,
+ // Marketplace folder. Same as an AT_CATEGORY but different display methods.
AT_CURRENT_OUTFIT = 46,
@@ -132,7 +135,16 @@ public:
AT_MESH = 49,
// Mesh data in our proprietary SLM format
- AT_COUNT = 50,
+ AT_RESERVED_1 = 50,
+ AT_RESERVED_2 = 51,
+ AT_RESERVED_3 = 52,
+ AT_RESERVED_4 = 53,
+ AT_RESERVED_5 = 54,
+ AT_RESERVED_6 = 55,
+
+ AT_SETTINGS = 56, // Collection of settings
+
+ AT_COUNT = 57,
// +*********************************************************+
// | TO ADD AN ELEMENT TO THIS ENUM: |
@@ -143,7 +155,7 @@ public:
// | 4. ADD TO LLViewerAssetType.cpp |
// | 5. ADD TO DEFAULT_ASSET_FOR_INV in LLInventoryType.cpp |
// +*********************************************************+
-
+ AT_UNKNOWN = 255,
AT_NONE = -1
};
diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp
index e6b688ee0..3cb14a2ca 100644
--- a/indra/llcommon/llerror.cpp
+++ b/indra/llcommon/llerror.cpp
@@ -120,6 +120,7 @@ namespace {
LL_INFOS() << "Error setting log file to " << filename << LL_ENDL;
}
mWantsTime = true;
+ mWantsTags = true;
}
~RecordToFile()
@@ -252,23 +253,13 @@ namespace
{
#ifdef __GNUC__
// GCC: type_info::name() returns a mangled class name,st demangle
-
- static size_t abi_name_len = 100;
- static char* abi_name_buf = (char*)malloc(abi_name_len);
- // warning: above is voodoo inferred from the GCC manual,
- // do NOT change
-
- int status;
- // We don't use status, and shouldn't have to pass apointer to it
- // but gcc 3.3 libstc++'s implementation of demangling is broken
- // and fails without.
-
- char* name = abi::__cxa_demangle(type.name(),
- abi_name_buf, &abi_name_len, &status);
- // this call can realloc the abi_name_buf pointer (!)
-
- return name ? name : type.name();
-
+ // passing nullptr, 0 forces allocation of a unique buffer we can free
+ // fixing MAINT-8724 on OSX 10.14
+ int status = -1;
+ char* name = abi::__cxa_demangle(type.name(), nullptr, 0, &status);
+ std::string result(name ? name : type.name());
+ free(name);
+ return result;
#elif LL_WINDOWS
// DevStudio: type_info::name() includes the text "class " at the start
@@ -600,7 +591,7 @@ namespace LLError
mFunctionString += std::string(mFunction) + ":";
for (size_t i = 0; i < mTagCount; i++)
{
- mTagString += std::string("#") + mTags[i] + ((i == mTagCount - 1) ? "" : " ");
+ mTagString += std::string("#") + mTags[i] + ((i == mTagCount - 1) ? "" : ",");
}
}
}
@@ -983,13 +974,19 @@ namespace
}
if (show_level && r->wantsLevel())
- {
- message_stream << site.mLevelString << " ";
- }
+ {
+ message_stream << site.mLevelString;
+ }
if (show_tags && r->wantsTags())
{
- message_stream << site.mTagString << " ";
+ message_stream << site.mTagString;
+ }
+
+ if ((show_level && r->wantsLevel())||
+ (show_tags && r->wantsTags()))
+ {
+ message_stream << " ";
}
if (show_function && r->wantsFunctionName())
diff --git a/indra/llcommon/llformat.cpp b/indra/llcommon/llformat.cpp
index f9f16006a..834bcf753 100644
--- a/indra/llcommon/llformat.cpp
+++ b/indra/llcommon/llformat.cpp
@@ -36,18 +36,38 @@
#include "llformat.h"
#include
+#include
// common used function with va_list argument
// wrapper for vsnprintf to be called from llformatXXX functions.
-static void va_format(std::string& out, const char *fmt, va_list va)
+static void va_format(std::string& out, const char *fmt, va_list& va)
{
- char tstr[1024]; /* Flawfinder: ignore */
-#if LL_WINDOWS
- _vsnprintf(tstr, 1024, fmt, va);
+ if (!fmt || !fmt[0]) return; // Don't bother if null or empty c_str
+
+ typedef typename std::vector> vec_t;
+ static thread_local vec_t charvector(1024); // Evolves into charveleon
+ #define vsnprintf(va) std::vsnprintf(charvector.data(), charvector.capacity(), fmt, va)
+#ifdef LL_WINDOWS // We don't have to copy on windows
+ #define va2 va
#else
- vsnprintf(tstr, 1024, fmt, va); /* Flawfinder: ignore */
+ va_list va2;
+ va_copy(va2, va);
#endif
- out.assign(tstr);
+ const auto smallsize(charvector.capacity());
+ const auto size = vsnprintf(va);
+ if (size < 0)
+ {
+ LL_ERRS() << "Encoding 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
+ vsnprintf(va2);
+ }
+#ifndef LL_WINDOWS
+ va_end(va2);
+#endif
+ out.assign(charvector.data());
}
std::string llformat(const char *fmt, ...)
diff --git a/indra/llcommon/llsdjson.cpp b/indra/llcommon/llsdjson.cpp
new file mode 100644
index 000000000..5b49f247a
--- /dev/null
+++ b/indra/llcommon/llsdjson.cpp
@@ -0,0 +1,126 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check it.
+// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+/**
+ * @file llsdjson.cpp
+ * @brief LLSD flexible data system
+ *
+ * $LicenseInfo:firstyear=2015&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2015, 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$
+ */
+
+// Must turn on conditional declarations in header file so definitions end up
+// with proper linkage.
+#define LLSD_DEBUG_INFO
+#include "linden_common.h"
+
+#include "llsdjson.h"
+
+#include "llerror.h"
+
+
+//=========================================================================
+LLSD LlsdFromJson(const nlohmann::json &val)
+{
+ LLSD result;
+
+ switch (val.type())
+ {
+ default:
+ case nlohmann::json::value_t::null:
+ break;
+ case nlohmann::json::value_t::number_integer:
+ result = LLSD(val.get());
+ break;
+ case nlohmann::json::value_t::number_unsigned:
+ result = LLSD(val.get());
+ break;
+ case nlohmann::json::value_t::number_float:
+ result = LLSD(val.get());
+ break;
+ case nlohmann::json::value_t::string:
+ result = LLSD(val.get());
+ break;
+ case nlohmann::json::value_t::boolean:
+ result = LLSD(val.get());
+ break;
+ case nlohmann::json::value_t::array:
+ result = LLSD::emptyArray();
+ for (const auto &element : val)
+ {
+ result.append(LlsdFromJson(element));
+ }
+ break;
+ case nlohmann::json::value_t::object:
+ result = LLSD::emptyMap();
+ for (auto it = val.cbegin(); it != val.cend(); ++it)
+ {
+ result[it.key()] = LlsdFromJson(it.value());
+ }
+ break;
+ }
+ return result;
+}
+
+//=========================================================================
+nlohmann::json LlsdToJson(const LLSD &val)
+{
+ nlohmann::json result;
+
+ switch (val.type())
+ {
+ case LLSD::TypeUndefined:
+ result = nullptr;
+ break;
+ case LLSD::TypeBoolean:
+ result = val.asBoolean();
+ break;
+ case LLSD::TypeInteger:
+ result = val.asInteger();
+ break;
+ case LLSD::TypeReal:
+ result = val.asReal();
+ break;
+ case LLSD::TypeURI:
+ case LLSD::TypeDate:
+ case LLSD::TypeUUID:
+ case LLSD::TypeString:
+ result = val.asString();
+ break;
+ case LLSD::TypeMap:
+ for (LLSD::map_const_iterator it = val.beginMap(); it != val.endMap(); ++it)
+ {
+ result[it->first] = LlsdToJson(it->second);
+ }
+ break;
+ case LLSD::TypeArray:
+ for (LLSD::array_const_iterator it = val.beginArray(); it != val.endArray(); ++it)
+ {
+ result.push_back(LlsdToJson(*it));
+ }
+ break;
+ case LLSD::TypeBinary:
+ default:
+ LL_ERRS("LlsdToJson") << "Unsupported conversion to JSON from LLSD type (" << val.type() << ")." << LL_ENDL;
+ break;
+ }
+
+ return result;
+}
diff --git a/indra/llcommon/llsdjson.h b/indra/llcommon/llsdjson.h
new file mode 100644
index 000000000..bc76acbc8
--- /dev/null
+++ b/indra/llcommon/llsdjson.h
@@ -0,0 +1,77 @@
+/**
+ * @file llsdjson.cpp
+ * @brief LLSD flexible data system
+ *
+ * $LicenseInfo:firstyear=2015&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2015, 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_LLSDJSON_H
+#define LL_LLSDJSON_H
+
+#include
+#include
+#include
+
+#include "stdtypes.h"
+
+#include "llsd.h"
+#include
+
+/// Convert a parsed JSON structure into LLSD maintaining member names and
+/// array indexes.
+/// JSON/JavaScript types are converted as follows:
+///
+/// JSON Type | LLSD Type
+/// --------------+--------------
+/// null | undefined
+/// integer | LLSD::Integer
+/// unsigned | LLSD::Integer
+/// real/numeric | LLSD::Real
+/// string | LLSD::String
+/// boolean | LLSD::Boolean
+/// array | LLSD::Array
+/// object | LLSD::Map
+///
+/// For maps and arrays child entries will be converted and added to the structure.
+/// Order is preserved for an array but not for objects.
+LLSD LlsdFromJson(const nlohmann::json &val);
+
+/// Convert an LLSD object into Parsed JSON object maintaining member names and
+/// array indexs.
+///
+/// Types are converted as follows:
+/// LLSD Type | JSON Type
+/// --------------+----------------
+/// TypeUndefined | null
+/// TypeBoolean | boolean
+/// TypeInteger | integer
+/// TypeReal | real/numeric
+/// TypeString | string
+/// TypeURI | string
+/// TypeDate | string
+/// TypeUUID | string
+/// TypeMap | object
+/// TypeArray | array
+/// TypeBinary | unsupported
+nlohmann::json LlsdToJson(const LLSD &val);
+
+#endif // LL_LLSDJSON_H
diff --git a/indra/llcommon/llstring.cpp b/indra/llcommon/llstring.cpp
index dc1236fce..7203b4d6e 100644
--- a/indra/llcommon/llstring.cpp
+++ b/indra/llcommon/llstring.cpp
@@ -1,3 +1,5 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check it.
+// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
/**
* @file llstring.cpp
* @brief String utility functions and the std::string class.
@@ -28,12 +30,17 @@
#include "llstring.h"
#include "llerror.h"
+#include "llfasttimer.h"
+#include "llsd.h"
#if LL_WINDOWS
#include "llwin32headerslean.h"
#include // for WideCharToMultiByte
#endif
+LLTrace::BlockTimerStatHandle FT_STRING_FORMAT("String Format");
+
+
std::string ll_safe_string(const char* in)
{
if(in) return std::string(in);
@@ -47,6 +54,23 @@ std::string ll_safe_string(const char* in, S32 maxlen)
return std::string();
}
+bool is_char_hex(char hex)
+{
+ if((hex >= '0') && (hex <= '9'))
+ {
+ return true;
+ }
+ else if((hex >= 'a') && (hex <='f'))
+ {
+ return true;
+ }
+ else if((hex >= 'A') && (hex <='F'))
+ {
+ return true;
+ }
+ return false; // uh - oh, not hex any more...
+}
+
U8 hex_as_nybble(char hex)
{
if((hex >= '0') && (hex <= '9'))
@@ -85,7 +109,7 @@ bool iswindividual(llwchar elem)
bool _read_file_into_string(std::string& str, const std::string& filename)
{
- llifstream ifs(filename, llifstream::binary);
+ llifstream ifs(filename.c_str(), llifstream::binary);
if (!ifs.is_open())
{
LL_INFOS() << "Unable to open file " << filename << LL_ENDL;
@@ -552,6 +576,33 @@ std::string utf8str_truncate(const std::string& utf8str, const S32 max_len)
}
}
+std::string utf8str_symbol_truncate(const std::string& utf8str, const S32 symbol_len)
+{
+ if (0 == symbol_len)
+ {
+ return std::string();
+ }
+ if ((S32)utf8str.length() <= symbol_len)
+ {
+ return utf8str;
+ }
+ else
+ {
+ int len = 0, byteIndex = 0;
+ const char* aStr = utf8str.c_str();
+ size_t origSize = utf8str.size();
+
+ for (byteIndex = 0; len < symbol_len && byteIndex < origSize; byteIndex++)
+ {
+ if ((aStr[byteIndex] & 0xc0) != 0x80)
+ {
+ len += 1;
+ }
+ }
+ return utf8str.substr(0, byteIndex);
+ }
+}
+
std::string utf8str_substChar(
const std::string& utf8str,
const llwchar target_char,
@@ -628,10 +679,10 @@ std::string ll_convert_wide_to_string(const wchar_t* in, unsigned int code_page)
0,
in,
len_in,
- NULL,
+ nullptr,
0,
- 0,
- 0);
+ nullptr,
+ nullptr);
// We will need two more bytes for the double NULL ending
// created in WideCharToMultiByte().
char* pout = new char [len_out + 2];
@@ -645,8 +696,8 @@ std::string ll_convert_wide_to_string(const wchar_t* in, unsigned int code_page)
len_in,
pout,
len_out,
- 0,
- 0);
+ nullptr,
+ nullptr);
out.assign(pout);
delete[] pout;
}
@@ -667,8 +718,8 @@ wchar_t* ll_convert_string_to_wide(const std::string& in, unsigned int code_page
// reserve place to NULL terminator
int output_str_len = in.length();
wchar_t* w_out = new wchar_t[output_str_len + 1];
-
memset(w_out, 0, output_str_len + 1);
+
int real_output_str_len = MultiByteToWideChar (code_page, 0, in.c_str(), in.length(), w_out, output_str_len);
//looks like MultiByteToWideChar didn't add null terminator to converted string, see EXT-4858.
@@ -689,7 +740,7 @@ std::string ll_convert_string_to_utf8_string(const std::string& in)
long LLStringOps::sPacificTimeOffset = 0;
long LLStringOps::sLocalTimeOffset = 0;
-bool LLStringOps::sPacificDaylightTime = 0;
+bool LLStringOps::sPacificDaylightTime = false;
std::map LLStringOps::datetimeToCodes;
std::vector LLStringOps::sWeekDayList;
@@ -708,7 +759,7 @@ S32 LLStringOps::collate(const llwchar* a, const llwchar* b)
#if LL_WINDOWS
// in Windows, wide string functions operator on 16-bit strings,
// not the proper 32 bit wide string
- return strcmp(wstring_to_utf8str(LLWString(a)).c_str(), wstring_to_utf8str(LLWString(b)).c_str());
+ return strcoll(wstring_to_utf8str(LLWString(a)).c_str(), wstring_to_utf8str(LLWString(b)).c_str());
#else
return wcscoll(a, b);
#endif
@@ -719,7 +770,7 @@ void LLStringOps::setupDatetimeInfo (bool daylight)
time_t nowT, localT, gmtT;
struct tm * tmpT;
- nowT = time (NULL);
+ nowT = time (nullptr);
tmpT = gmtime (&nowT);
gmtT = mktime (tmpT);
@@ -799,7 +850,7 @@ void LLStringOps::setupDayFormat(const std::string& data)
}
-std::string LLStringOps::getDatetimeCode (std::string key)
+std::string LLStringOps::getDatetimeCode(const std::string& key)
{
std::map::iterator iter;
@@ -1187,6 +1238,7 @@ bool LLStringUtil::formatDatetime(std::string& replacement, std::string token,
template<>
S32 LLStringUtil::format(std::string& s, const format_map_t& substitutions)
{
+ LL_RECORD_BLOCK_TIME(FT_STRING_FORMAT);
S32 res = 0;
std::string output;
@@ -1259,6 +1311,7 @@ S32 LLStringUtil::format(std::string& s, const format_map_t& substitutions)
template<>
S32 LLStringUtil::format(std::string& s, const LLSD& substitutions)
{
+ LL_RECORD_BLOCK_TIME(FT_STRING_FORMAT);
S32 res = 0;
if (!substitutions.isMap())
@@ -1387,7 +1440,7 @@ void LLStringUtilBase::testHarness()
s2.erase( 4, 1 );
llassert( s2 == "hell");
- s2.insert( 0, 1, 'y' );
+ s2.insert( s2.begin(), 'y' );
llassert( s2 == "yhell");
s2.erase( 1, 3 );
llassert( s2 == "yl");
diff --git a/indra/llcommon/llstring.h b/indra/llcommon/llstring.h
index 091849277..35407ca4e 100644
--- a/indra/llcommon/llstring.h
+++ b/indra/llcommon/llstring.h
@@ -29,8 +29,11 @@
#include
#include
-#include
+//#include
#include
+#include
+#include
+#include
#include "llsd.h"
#include "llfasttimer.h"
@@ -49,6 +52,7 @@
#endif
const char LL_UNKNOWN_CHAR = '?';
+class LLSD;
#if LL_DARWIN || LL_LINUX || LL_SOLARIS
// Template specialization of char_traits for U16s. Only necessary on Mac and Linux (exists on Windows already)
@@ -209,7 +213,7 @@ public:
// currently in daylight savings time?
static bool getPacificDaylightTime(void) { return sPacificDaylightTime;}
- static std::string getDatetimeCode (std::string key);
+ static std::string getDatetimeCode (const std::string& key);
// Express a value like 1234567 as "1.23M"
static std::string getReadableNumber(F64 num);
@@ -301,7 +305,7 @@ public:
static bool isValidIndex(const string_type& string, size_type i)
{
- return !string.empty() && (0 <= i) && (i <= string.size());
+ return !string.empty() && (i <= string.size());
}
static bool contains(const string_type& string, T c, size_type i=0)
@@ -311,6 +315,7 @@ public:
static void trimHead(string_type& string);
static void trimTail(string_type& string);
+ static void trimTail(string_type& string, const string_type& tokens);
static void trim(string_type& string) { trimHead(string); trimTail(string); }
static void truncate(string_type& string, size_type count);
@@ -340,6 +345,7 @@ public:
static void addCRLF(string_type& string);
static void removeCRLF(string_type& string);
+ static void removeWindowsCR(string_type& string);
static void replaceTabsWithSpaces( string_type& string, size_type spaces_per_tab );
static void replaceNonstandardASCII( string_type& string, T replacement );
@@ -448,7 +454,7 @@ public:
struct LLDictionaryLess
{
public:
- bool operator()(const std::string& a, const std::string& b)
+ bool operator()(const std::string& a, const std::string& b) const
{
return (LLStringUtil::precedesDict(a, b) ? true : false);
}
@@ -478,6 +484,7 @@ inline std::string chop_tail_copy(
* @brief This translates a nybble stored as a hex value from 0-f back
* to a nybble in the low order bits of the return byte.
*/
+LL_COMMON_API bool is_char_hex(char hex);
LL_COMMON_API U8 hex_as_nybble(char hex);
/**
@@ -532,10 +539,13 @@ LL_COMMON_API S32 wchar_to_utf8chars(llwchar inchar, char* outchars);
LL_COMMON_API std::string wstring_to_utf8str(const LLWString &utf32str, S32 len);
LL_COMMON_API std::string wstring_to_utf8str(const LLWString &utf32str);
-
LL_COMMON_API std::string utf16str_to_utf8str(const llutf16string &utf16str, S32 len);
LL_COMMON_API std::string utf16str_to_utf8str(const llutf16string &utf16str);
+#if LL_WINDOWS
+inline std::string wstring_to_utf8str(const llutf16string &utf16str) { return utf16str_to_utf8str(utf16str);}
+#endif
+
// Length of this UTF32 string in bytes when transformed to UTF8
LL_COMMON_API S32 wstring_utf8_length(const LLWString& wstr);
@@ -551,7 +561,7 @@ LL_COMMON_API S32 utf16str_wstring_length(const llutf16string &utf16str, S32 len
LL_COMMON_API S32 wstring_utf16_length(const LLWString & wstr, S32 woffset, S32 wlen);
// Length in wstring (i.e., llwchar count) of a part of a wstring specified by utf16 length (i.e., utf16 units.)
-LL_COMMON_API S32 wstring_wstring_length_from_utf16_length(const LLWString & wstr, S32 woffset, S32 utf16_length, BOOL *unaligned = NULL);
+LL_COMMON_API S32 wstring_wstring_length_from_utf16_length(const LLWString & wstr, S32 woffset, S32 utf16_length, BOOL *unaligned = nullptr);
/**
* @brief Properly truncate a utf8 string to a maximum byte count.
@@ -571,6 +581,17 @@ LL_COMMON_API S32 utf8str_compare_insensitive(
const std::string& lhs,
const std::string& rhs);
+/**
+* @brief Properly truncate a utf8 string to a maximum character count.
+*
+* If symbol_len is longer than the string passed in, the return
+* value == utf8str.
+* @param utf8str A valid utf8 string to truncate.
+* @param symbol_len The maximum number of symbols in the return value.
+* @return Returns a valid utf8 string with symbol count <= max_len.
+*/
+LL_COMMON_API std::string utf8str_symbol_truncate(const std::string& utf8str, const S32 symbol_len);
+
/**
* @brief Replace all occurences of target_char with replace_char
*
@@ -813,8 +834,9 @@ public:
}
/// This implementation uses the answer cached by setiter().
- virtual bool escaped() const { return mIsEsc; }
- virtual T next()
+ bool escaped() const override { return mIsEsc; }
+
+ T next() override
{
// If we're looking at the escape character of an escape sequence,
// skip that character. This is the one time we can modify 'mIter'
@@ -830,21 +852,21 @@ public:
return result;
}
- virtual bool is(T ch) const
+ bool is(T ch) const override
{
// Like base-class is(), except that an escaped character matches
// nothing.
return (! done()) && (! mIsEsc) && *mIter == ch;
}
- virtual bool oneof(const string_type& delims) const
+ bool oneof(const string_type& delims) const override
{
// Like base-class oneof(), except that an escaped character matches
// nothing.
return (! done()) && (! mIsEsc) && LLStringUtilBase::contains(delims, *mIter);
}
- virtual bool collect_until(string_type& into, const_iterator from, T delim)
+ bool collect_until(string_type& into, const_iterator from, T delim) override
{
// Deal with escapes in the characters we collect; that is, an escaped
// character must become just that character without the preceding
@@ -1158,7 +1180,7 @@ BOOL LLStringUtilBase::precedesDict( const string_type& a, const string_type&
{
if( a.size() && b.size() )
{
- return (LLStringUtilBase::compareDict(a.c_str(), b.c_str()) < 0);
+ return (LLStringUtilBase::compareDict(a, b) < 0);
}
else
{
@@ -1213,7 +1235,7 @@ void LLStringUtilBase::trimHead(string_type& string)
template
void LLStringUtilBase::trimTail(string_type& string)
{
- if( string.size() )
+ if(!string.empty())
{
size_type len = string.length();
size_type i = len;
@@ -1226,12 +1248,31 @@ void LLStringUtilBase::trimTail(string_type& string)
}
}
+template
+void LLStringUtilBase::trimTail(string_type& string, const string_type& tokens)
+{
+ if(!string.empty())
+ {
+ size_type len = string.length();
+ size_type i = len;
+ while( i > 0 && (tokens.find_first_of(string[i-1]) != string_type::npos) )
+ {
+ i--;
+ }
+
+ string.erase( i, len - i );
+ }
+}
+
// Replace line feeds with carriage return-line feed pairs.
//static
template
void LLStringUtilBase::addCRLF(string_type& string)
{
+ if (string.empty())
+ return;
+
const T LF = 10;
const T CR = 13;
@@ -1274,6 +1315,9 @@ void LLStringUtilBase::addCRLF(string_type& string)
template
void LLStringUtilBase::removeCRLF(string_type& string)
{
+ if (string.empty())
+ return;
+
const T CR = 13;
size_type cr_count = 0;
@@ -1293,6 +1337,32 @@ void LLStringUtilBase::removeCRLF(string_type& string)
//static
template
+void LLStringUtilBase::removeWindowsCR(string_type& string)
+{
+ if (string.empty())
+ {
+ return;
+ }
+ const T LF = 10;
+ const T CR = 13;
+
+ size_type cr_count = 0;
+ size_type len = string.size();
+ size_type i;
+ for( i = 0; i < len - cr_count - 1; i++ )
+ {
+ if( string[i+cr_count] == CR && string[i+cr_count+1] == LF)
+ {
+ cr_count++;
+ }
+
+ string[i] = string[i+cr_count];
+ }
+ string.erase(i, cr_count);
+}
+
+//static
+template
void LLStringUtilBase::replaceChar( string_type& string, T target, T replacement )
{
size_type found_pos = 0;
@@ -1376,6 +1446,7 @@ BOOL LLStringUtilBase::containsNonprintable(const string_type& string)
return rv;
}
+// *TODO: reimplement in terms of algorithm
//static
template
void LLStringUtilBase::stripNonprintable(string_type& string)
@@ -1386,33 +1457,23 @@ void LLStringUtilBase::stripNonprintable(string_type& string)
{
return;
}
- size_t src_size = string.size();
- char* c_string = nullptr;
- try
- {
- c_string = new char[src_size + 1];
- }
- catch (const std::bad_alloc&)
- {
- return;
- }
- copy(c_string, string.c_str(), src_size+1);
- char* write_head = &c_string[0];
+ const size_t src_size = string.size();
+ auto c_string = std::make_unique(src_size + 1);
+
+ copy(c_string.get(), string.c_str(), src_size+1);
for (size_type i = 0; i < src_size; i++)
{
- char* read_head = &string[i];
- write_head = &c_string[j];
- if(!(*read_head < MIN))
+ if(string[i] >= MIN)
{
- *write_head = *read_head;
+ c_string[j] = string[i];
++j;
}
}
c_string[j]= '\0';
- string = c_string;
- delete []c_string;
+ string.assign(c_string.get());
}
+// *TODO: reimplement in terms of algorithm
template
std::basic_string LLStringUtilBase::quote(const string_type& str,
const string_type& triggers,
@@ -1434,7 +1495,9 @@ std::basic_string LLStringUtilBase::quote(const string_type& str,
}
// For whatever reason, we must quote this string.
+ auto needed_escapes = std::count(str.begin(), str.end(), '"');
string_type result;
+ result.reserve(len + (needed_escapes * escape.length()));
result.push_back('"');
for (typename string_type::const_iterator ci(str.begin()), cend(str.end()); ci != cend; ++ci)
{
diff --git a/indra/llcommon/lluri.cpp b/indra/llcommon/lluri.cpp
index b990dfe2a..5f5a67a88 100644
--- a/indra/llcommon/lluri.cpp
+++ b/indra/llcommon/lluri.cpp
@@ -1,3 +1,5 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check it.
+// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
/**
* @file lluri.cpp
* @author Phoenix
@@ -40,7 +42,8 @@
#include
#include
-void encode_character(std::ostream& ostr, std::string::value_type val)
+// static
+void LLURI::encodeCharacter(std::ostream& ostr, std::string::value_type val)
{
ostr << "%"
@@ -95,7 +98,7 @@ std::string LLURI::escape(
}
else
{
- encode_character(ostr, c);
+ encodeCharacter(ostr, c);
}
}
}
@@ -106,7 +109,7 @@ std::string LLURI::escape(
c = *it;
if(allowed.find(c) == std::string::npos)
{
- encode_character(ostr, c);
+ encodeCharacter(ostr, c);
}
else
{
@@ -129,11 +132,30 @@ std::string LLURI::unescape(const std::string& str)
{
++it;
if(it == end) break;
- U8 c = hex_as_nybble(*it++);
- c = c << 4;
- if (it == end) break;
- c |= hex_as_nybble(*it);
- ostr.put((char)c);
+
+ if(is_char_hex(*it))
+ {
+ U8 c = hex_as_nybble(*it++);
+
+ c = c << 4;
+ if (it == end) break;
+
+ if(is_char_hex(*it))
+ {
+ c |= hex_as_nybble(*it);
+ ostr.put((char)c);
+ }
+ else
+ {
+ ostr.put((char)c);
+ ostr.put(*it);
+ }
+ }
+ else
+ {
+ ostr.put('%');
+ ostr.put(*it);
+ }
}
else
{
@@ -169,11 +191,10 @@ namespace
{ return LLURI::escape(s, unreserved() + ":@!$'()*+,="); } // sub_delims - "&;" + ":@"
}
-// *TODO: Consider using curl. After http textures gets merged everywhere.
// static
std::string LLURI::escape(const std::string& str)
{
- static std::string default_allowed(unreserved() + ":@!$'()*+,=/?");
+ static std::string default_allowed = unreserved();
static bool initialized = false;
if(!initialized)
{
@@ -228,7 +249,8 @@ void LLURI::parseAuthorityAndPathUsingOpaque()
{
if (mScheme == "http" || mScheme == "https" ||
mScheme == "ftp" || mScheme == "secondlife" ||
- mScheme == "x-grid-location-info")
+ mScheme == "x-grid-info" ||
+ mScheme == "x-grid-location-info") // legacy
{
if (mEscapedOpaque.substr(0,2) != "//")
{
@@ -401,6 +423,15 @@ LLURI LLURI::buildHTTP(const std::string& prefix,
return uri;
}
+// static
+LLURI LLURI::buildHTTP(const std::string& scheme,
+ const std::string& prefix,
+ const LLSD& path,
+ const LLSD& query)
+{
+ return buildHTTP(llformat("%s://%s", scheme.c_str(), prefix.c_str()), path, query);
+}
+
// static
LLURI LLURI::buildHTTP(const std::string& host,
const U32& port,
@@ -485,6 +516,14 @@ std::string LLURI::hostName() const
return unescape(host);
}
+std::string LLURI::hostNameAndPort() const
+{
+ std::string user, host, port;
+ findAuthorityParts(mEscapedAuthority, user, host, port);
+ return port.empty() ? unescape(host) : unescape(host + ":" + port);
+}
+
+
std::string LLURI::userName() const
{
std::string user, userPass, host, port;
diff --git a/indra/llcommon/lluri.h b/indra/llcommon/lluri.h
index 57bbedf42..faa5f3a75 100644
--- a/indra/llcommon/lluri.h
+++ b/indra/llcommon/lluri.h
@@ -4,31 +4,25 @@
* @date 2006-02-05
* @brief Declaration of the URI class.
*
- * $LicenseInfo:firstyear=2006&license=viewergpl$
- *
- * Copyright (c) 2006-2009, Linden Research, Inc.
- *
+ * $LicenseInfo:firstyear=2006&license=viewerlgpl$
* 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
+ * Copyright (C) 2010, Linden Research, Inc.
*
- * 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
+ * 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.
*
- * 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.
+ * 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.
*
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
+ * 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$
*/
@@ -72,6 +66,13 @@ public:
const std::string& prefix,
const LLSD& path,
const LLSD& query);
+
+ static LLURI buildHTTP(
+ const std::string& scheme,
+ const std::string& prefix,
+ const LLSD& path,
+ const LLSD& query);
+
///< prefix is either a full URL prefix of the form
/// "http://example.com:8080", or it can be simply a host and
/// optional port like "example.com" or "example.com:8080", in
@@ -99,20 +100,21 @@ public:
std::string scheme() const; ///< ex.: "http", note lack of colon
std::string opaque() const; ///< everything after the colon
- // for schemes that follow path like syntax (http, https, ftp)
- std::string authority() const; // ex.: "host.com:80"
- std::string hostName() const; // ex.: "host.com"
- std::string userName() const;
- std::string password() const;
- U16 hostPort() const; // ex.: 80, will include implicit port
- BOOL defaultPort() const; // true if port is default for scheme
- const std::string& escapedPath() const { return mEscapedPath; }
- std::string path() const; // ex.: "/abc/def", includes leading slash
- LLSD pathArray() const; // above decoded into an array of strings
- std::string query() const; // ex.: "x=34", section after "?"
- const std::string& escapedQuery() const { return mEscapedQuery; }
- LLSD queryMap() const; // above decoded into a map
- static LLSD queryMap(std::string escaped_query_string);
+ // for schemes that follow path like syntax (http, https, ftp)
+ std::string authority() const; // ex.: "user:pass@host.com:80"
+ std::string hostName() const; // ex.: "host.com"
+ std::string hostNameAndPort() const; // ex.: "host.com:80"
+ std::string userName() const;
+ std::string password() const;
+ U16 hostPort() const; // ex.: 80, will include implicit port
+ BOOL defaultPort() const; // true if port is default for scheme
+ const std::string& escapedPath() const { return mEscapedPath; }
+ std::string path() const; // ex.: "/abc/def", includes leading slash
+ LLSD pathArray() const; // above decoded into an array of strings
+ std::string query() const; // ex.: "x=34", section after "?"
+ const std::string& escapedQuery() const { return mEscapedQuery; }
+ LLSD queryMap() const; // above decoded into a map
+ static LLSD queryMap(std::string escaped_query_string);
/**
* @brief given a name value map, return a serialized query string.
@@ -127,27 +129,24 @@ public:
/** @name Escaping Utilities */
//@{
/**
- * @brief Escape a raw url with a reasonable set of allowed characters.
+ * @brief 'Escape' symbol into stream
*
- * The default set was chosen to match HTTP urls and general
- * guidelines for naming resources. Passing in a raw url does not
- * produce well defined results because you really need to know
- * which segments are path parts because path parts are supposed
- * to be escaped individually. The default set chosen is:
+ * @param ostr Output stream.
+ * @param val Symbol to encode.
+ */
+ static void encodeCharacter(std::ostream& ostr, std::string::value_type val);
+
+ /**
+ * @brief Escape the string passed except for unreserved
*
* ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
* 0123456789
* -._~
- * :@!$'()*+,=/?
*
- * *NOTE: This API is basically broken because it does not
- * allow you to specify significant path characters. For example,
- * if the filename actually contained a /, then you cannot use
- * this function to generate the serialized url for that
- * resource.
+ * @see http://www.ietf.org/rfc/rfc1738.txt
*
* @param str The raw URI to escape.
- * @return Returns the escaped uri or an empty string.
+ * @return Returns the rfc 1738 escaped uri or an empty string.
*/
static std::string escape(const std::string& str);
diff --git a/indra/llcommon/lluriparser.cpp b/indra/llcommon/lluriparser.cpp
new file mode 100644
index 000000000..e32d9f5c0
--- /dev/null
+++ b/indra/llcommon/lluriparser.cpp
@@ -0,0 +1,266 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check it.
+// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+/**
+ * @file lluriparser.cpp
+ * @author Protey
+ * @date 2014-10-07
+ * @brief Implementation of the LLUriParser class.
+ *
+ * $LicenseInfo:firstyear=2014&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2014, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+#include "lluriparser.h"
+
+LLUriParser::LLUriParser(const std::string& u)
+: mRes(0)
+, mTmpScheme(false)
+, mNormalizedTmp(false)
+{
+ mState.uri = &mUri;
+
+ if (u.find("://") == std::string::npos)
+ {
+ mNormalizedUri = "http://";
+ mTmpScheme = true;
+ }
+
+ mNormalizedUri += u;
+
+ mRes = parse();
+}
+
+LLUriParser::~LLUriParser()
+{
+ uriFreeUriMembersA(&mUri);
+}
+
+S32 LLUriParser::parse()
+{
+ mRes = uriParseUriA(&mState, mNormalizedUri.c_str());
+ return mRes;
+}
+
+const char * LLUriParser::scheme() const
+{
+ return mScheme.c_str();
+}
+
+void LLUriParser::scheme(const std::string& s)
+{
+ mTmpScheme = !s.size();
+ mScheme = s;
+}
+
+const char * LLUriParser::port() const
+{
+ return mPort.c_str();
+}
+
+void LLUriParser::port(const std::string& s)
+{
+ mPort = s;
+}
+
+const char * LLUriParser::host() const
+{
+ return mHost.c_str();
+}
+
+void LLUriParser::host(const std::string& s)
+{
+ mHost = s;
+}
+
+const char * LLUriParser::path() const
+{
+ return mPath.c_str();
+}
+
+void LLUriParser::path(const std::string& s)
+{
+ mPath = s;
+}
+
+const char * LLUriParser::query() const
+{
+ return mQuery.c_str();
+}
+
+void LLUriParser::query(const std::string& s)
+{
+ mQuery = s;
+}
+
+const char * LLUriParser::fragment() const
+{
+ return mFragment.c_str();
+}
+
+void LLUriParser::fragment(const std::string& s)
+{
+ mFragment = s;
+}
+
+void LLUriParser::textRangeToString(UriTextRangeA& textRange, std::string& str)
+{
+ if (textRange.first != nullptr && textRange.afterLast != nullptr && textRange.first < textRange.afterLast)
+ {
+ const ptrdiff_t len = textRange.afterLast - textRange.first;
+ str.assign(textRange.first, static_cast(len));
+ }
+ else
+ {
+ str = LLStringUtil::null;
+ }
+}
+
+void LLUriParser::extractParts()
+{
+ if (mTmpScheme || mNormalizedTmp)
+ {
+ mScheme.clear();
+ }
+ else
+ {
+ textRangeToString(mUri.scheme, mScheme);
+ }
+
+ textRangeToString(mUri.hostText, mHost);
+ textRangeToString(mUri.portText, mPort);
+ textRangeToString(mUri.query, mQuery);
+ textRangeToString(mUri.fragment, mFragment);
+
+ UriPathSegmentA * pathHead = mUri.pathHead;
+ while (pathHead)
+ {
+ std::string partOfPath;
+ textRangeToString(pathHead->text, partOfPath);
+
+ mPath += '/';
+ mPath += partOfPath;
+
+ pathHead = pathHead->next;
+ }
+}
+
+S32 LLUriParser::normalize()
+{
+ mNormalizedTmp = mTmpScheme;
+ if (!mRes)
+ {
+ mRes = uriNormalizeSyntaxExA(&mUri, URI_NORMALIZE_SCHEME | URI_NORMALIZE_HOST);
+
+ if (!mRes)
+ {
+ S32 chars_required;
+ mRes = uriToStringCharsRequiredA(&mUri, &chars_required);
+
+ if (!mRes)
+ {
+ chars_required++;
+ std::vector label_buf(chars_required);
+ mRes = uriToStringA(&label_buf[0], &mUri, chars_required, nullptr);
+
+ if (!mRes)
+ {
+ mNormalizedUri = &label_buf[mTmpScheme ? 7 : 0];
+ mTmpScheme = false;
+ }
+ }
+ }
+ }
+
+ if(mTmpScheme)
+ {
+ mNormalizedUri = mNormalizedUri.substr(7);
+ mTmpScheme = false;
+ }
+
+ return mRes;
+}
+
+void LLUriParser::glue(std::string& uri) const
+{
+ std::string first_part;
+ glueFirst(first_part);
+
+ std::string second_part;
+ glueSecond(second_part);
+
+ uri = first_part + second_part;
+}
+
+void LLUriParser::glueFirst(std::string& uri, bool use_scheme) const
+{
+ if (use_scheme && mScheme.size())
+ {
+ uri = mScheme;
+ uri += "://";
+ }
+ else
+ {
+ uri.clear();
+ }
+
+ uri += mHost;
+}
+
+void LLUriParser::glueSecond(std::string& uri) const
+{
+ if (mPort.size())
+ {
+ uri = ':';
+ uri += mPort;
+ }
+ else
+ {
+ uri.clear();
+ }
+
+ uri += mPath;
+
+ if (mQuery.size())
+ {
+ uri += '?';
+ uri += mQuery;
+ }
+
+ if (mFragment.size())
+ {
+ uri += '#';
+ uri += mFragment;
+ }
+}
+
+bool LLUriParser::test() const
+{
+ std::string uri;
+ glue(uri);
+
+ return uri == mNormalizedUri;
+}
+
+const char * LLUriParser::normalizedUri() const
+{
+ return mNormalizedUri.c_str();
+}
diff --git a/indra/llcommon/lluriparser.h b/indra/llcommon/lluriparser.h
new file mode 100644
index 000000000..773d4189f
--- /dev/null
+++ b/indra/llcommon/lluriparser.h
@@ -0,0 +1,87 @@
+/**
+ * @file lluriparser.h
+ * @author Protey
+ * @date 20146-10-07
+ * @brief Declaration of the UriParser class.
+ *
+ * $LicenseInfo:firstyear=2014&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2014, 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_LLURIPARSER_H
+#define LL_LLURIPARSER_H
+
+#include
+#include
+
+class LL_COMMON_API LLUriParser
+{
+public:
+ LLUriParser(const std::string& u);
+ ~LLUriParser();
+
+ const char * scheme() const;
+ void scheme (const std::string& s);
+
+ const char * port() const;
+ void port (const std::string& s);
+
+ const char * host() const;
+ void host (const std::string& s);
+
+ const char * path() const;
+ void path (const std::string& s);
+
+ const char * query() const;
+ void query (const std::string& s);
+
+ const char * fragment() const;
+ void fragment (const std::string& s);
+
+ const char * normalizedUri() const;
+
+ void extractParts();
+ void glue(std::string& uri) const;
+ void glueFirst(std::string& uri, bool use_scheme = true) const;
+ void glueSecond(std::string& uri) const;
+ bool test() const;
+ S32 normalize();
+
+private:
+ S32 parse();
+ void textRangeToString(UriTextRangeA& textRange, std::string& str);
+ std::string mScheme;
+ std::string mHost;
+ std::string mPort;
+ std::string mPath;
+ std::string mQuery;
+ std::string mFragment;
+ std::string mNormalizedUri;
+
+ UriParserStateA mState;
+ UriUriA mUri;
+
+ S32 mRes;
+ bool mTmpScheme;
+ bool mNormalizedTmp;
+};
+
+#endif // LL_LLURIPARSER_H
diff --git a/indra/llinventory/llfoldertype.cpp b/indra/llinventory/llfoldertype.cpp
index bb8365528..5fe513310 100644
--- a/indra/llinventory/llfoldertype.cpp
+++ b/indra/llinventory/llfoldertype.cpp
@@ -103,6 +103,9 @@ LLFolderDictionary::LLFolderDictionary()
addEntry(LLFolderType::FT_OUTBOX, new FolderEntry("outbox", TRUE));
addEntry(LLFolderType::FT_BASIC_ROOT, new FolderEntry("basic_rt", TRUE));
+ addEntry(LLFolderType::FT_MARKETPLACE_LISTINGS, new FolderEntry("merchant", FALSE));
+ addEntry(LLFolderType::FT_MARKETPLACE_STOCK, new FolderEntry("stock", FALSE));
+ addEntry(LLFolderType::FT_MARKETPLACE_VERSION, new FolderEntry("version", FALSE));
addEntry(LLFolderType::FT_SUITCASE, new FolderEntry("suitcase", TRUE));
addEntry(LLFolderType::FT_NONE, new FolderEntry("-1", FALSE));
diff --git a/indra/llinventory/llfoldertype.h b/indra/llinventory/llfoldertype.h
index bb9a3f213..bea5dc379 100644
--- a/indra/llinventory/llfoldertype.h
+++ b/indra/llinventory/llfoldertype.h
@@ -94,6 +94,9 @@ public:
FT_BASIC_ROOT = 52,
+ FT_MARKETPLACE_LISTINGS = 53,
+ FT_MARKETPLACE_STOCK = 54,
+ FT_MARKETPLACE_VERSION = 55, // Note: We actually *never* create folders with that type. This is used for icon override only.
FT_SUITCASE = 100,
FT_COUNT,
diff --git a/indra/llinventory/llinventorytype.cpp b/indra/llinventory/llinventorytype.cpp
index 78651b55f..fcef1611c 100644
--- a/indra/llinventory/llinventorytype.cpp
+++ b/indra/llinventory/llinventorytype.cpp
@@ -85,6 +85,7 @@ LLInventoryDictionary::LLInventoryDictionary()
addEntry(LLInventoryType::IT_ANIMATION, new InventoryEntry("animation", "animation", 1, LLAssetType::AT_ANIMATION));
addEntry(LLInventoryType::IT_GESTURE, new InventoryEntry("gesture", "gesture", 1, LLAssetType::AT_GESTURE));
addEntry(LLInventoryType::IT_MESH, new InventoryEntry("mesh", "mesh", 1, LLAssetType::AT_MESH));
+ addEntry(LLInventoryType::IT_SETTINGS, new InventoryEntry("settings", "settings", 1, LLAssetType::AT_SETTINGS));
}
@@ -145,6 +146,15 @@ DEFAULT_ASSET_FOR_INV_TYPE[LLAssetType::AT_COUNT] =
LLInventoryType::IT_NONE, // 47 AT_NONE
LLInventoryType::IT_NONE, // 48 AT_NONE
LLInventoryType::IT_MESH, // 49 AT_MESH
+
+ LLInventoryType::IT_NONE, // 50 AT_RESERVED_1
+ LLInventoryType::IT_NONE, // 52 AT_RESERVED_2
+ LLInventoryType::IT_NONE, // 53 AT_RESERVED_3
+ LLInventoryType::IT_NONE, // 54 AT_RESERVED_4
+ LLInventoryType::IT_NONE, // 55 AT_RESERVED_5
+ LLInventoryType::IT_NONE, // 56 AT_RESERVED_6
+
+ LLInventoryType::IT_SETTINGS, // 57 AT_SETTINGS
};
// static
diff --git a/indra/llinventory/llinventorytype.h b/indra/llinventory/llinventorytype.h
index b444ecfa5..1d9627ffb 100644
--- a/indra/llinventory/llinventorytype.h
+++ b/indra/llinventory/llinventorytype.h
@@ -62,8 +62,10 @@ public:
IT_ANIMATION = 19,
IT_GESTURE = 20,
IT_MESH = 22,
- IT_COUNT = 23,
+ IT_SETTINGS = 25,
+ IT_COUNT = 26,
+ IT_UNKNOWN = 255,
IT_NONE = -1
};
@@ -108,8 +110,14 @@ public:
ICONNAME_LINKFOLDER,
ICONNAME_MESH,
+ ICONNAME_SETTINGS,
+ ICONNAME_SETTINGS_SKY,
+ ICONNAME_SETTINGS_WATER,
+ ICONNAME_SETTINGS_DAY,
+
ICONNAME_CLOTHING_UNKNOWN,
ICONNAME_INVALID,
+ ICONNAME_UNKNOWN,
ICONNAME_COUNT,
ICONNAME_NONE = -1
};
diff --git a/indra/llinventory/llparcelflags.h b/indra/llinventory/llparcelflags.h
index 343044727..9d4884e32 100644
--- a/indra/llinventory/llparcelflags.h
+++ b/indra/llinventory/llparcelflags.h
@@ -68,7 +68,7 @@ const U32 PF_ALLOW_ALL_OBJECT_ENTRY = 1 << 27; // Allow all objects to enter a
const U32 PF_ALLOW_GROUP_OBJECT_ENTRY = 1 << 28; // Only allow group (and owner) objects to enter the parcel
const U32 PF_ALLOW_VOICE_CHAT = 1 << 29; // Allow residents to use voice chat on this parcel
const U32 PF_USE_ESTATE_VOICE_CHAN = 1 << 30;
-const U32 PF_DENY_AGEUNVERIFIED = 1 << 31; // Prevent residents who aren't age-verified
+const U32 PF_DENY_AGEUNVERIFIED = 1U << 31; // Prevent residents who aren't age-verified
// NOTE: At one point we have used all of the bits.
// We have deprecated two of them in 1.19.0 which *could* be reused,
// but only after we are certain there are no simstates using those bits.
diff --git a/indra/llmath/llmath.h b/indra/llmath/llmath.h
index ecf324465..a802da5bd 100644
--- a/indra/llmath/llmath.h
+++ b/indra/llmath/llmath.h
@@ -395,7 +395,7 @@ inline U32 get_lower_power_two(U32 val, U32 max_power_two)
{
if(!max_power_two)
{
- max_power_two = 1 << 31 ;
+ max_power_two = 1U << 31 ;
}
if(max_power_two & (max_power_two - 1))
{
@@ -417,7 +417,7 @@ inline U32 get_next_power_two(U32 val, U32 max_power_two)
{
if(!max_power_two)
{
- max_power_two = 1 << 31 ;
+ max_power_two = 1U << 31 ;
}
if(val >= max_power_two)
diff --git a/indra/llmessage/aicurlthread.cpp b/indra/llmessage/aicurlthread.cpp
index a66790f1d..c23beea84 100644
--- a/indra/llmessage/aicurlthread.cpp
+++ b/indra/llmessage/aicurlthread.cpp
@@ -2291,12 +2291,13 @@ size_t BufferedCurlEasyRequest::curlHeaderCallback(char* data, size_t size, size
}
else
{
- reason = "Unexpected HTTP status.";
+ //reason = "Unexpected HTTP status.";
LL_WARNS() << "Received unexpected status value from server (" << status << "): \"" << header << "\"" << LL_ENDL;
}
+ // Singu TODO: WHAT THE HELL WAS THIS?! LYING? WHY WERE WE LYING???? Responders USE These Codes!!!!!
// Either way, this status value is not understood (or taken into account).
// Set it to internal error so that the rest of code treats it as an error.
- status = HTTP_INTERNAL_ERROR_OTHER;
+ if (!status) status = HTTP_INTERNAL_ERROR_OTHER;
}
self_w->received_HTTP_header();
self_w->setStatusAndReason(status, reason);
diff --git a/indra/llprimitive/object_flags.h b/indra/llprimitive/object_flags.h
index f48b97d58..e97014470 100644
--- a/indra/llprimitive/object_flags.h
+++ b/indra/llprimitive/object_flags.h
@@ -69,6 +69,7 @@ const U32 FLAGS_TEMPORARY = (1U << 30);
//const U32 FLAGS_UNUSED_007 = (1U << 31); // was FLAGS_ZLIB_COMPRESSED
const U32 FLAGS_LOCAL = FLAGS_ANIM_SOURCE | FLAGS_CAMERA_SOURCE;
+const U32 FLAGS_WORLD = FLAGS_USE_PHYSICS | FLAGS_PHANTOM | FLAGS_TEMPORARY_ON_REZ;
typedef enum e_havok_joint_type
{
diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp
index d1e5dd41a..c1a9c51e9 100644
--- a/indra/llrender/llimagegl.cpp
+++ b/indra/llrender/llimagegl.cpp
@@ -584,7 +584,7 @@ void LLImageGL::setSize(S32 width, S32 height, S32 ncomponents, S32 discard_leve
// Check if dimensions are a power of two!
if (!checkSize(width,height))
{
- LL_WARNS() << llformat("Texture has non power of two dimension: %dx%d",width,height) << " Unless on Aurora-Sim, beware." << LL_ENDL;
+ LL_WARNS() << llformat("Texture has non power of two dimension: %dx%d",width,height) << " Unless on WhiteCore, beware." << LL_ENDL;
}
if (mTexName)
diff --git a/indra/llrender/llpostprocess.cpp b/indra/llrender/llpostprocess.cpp
index 0bc624fbb..505dcf670 100644
--- a/indra/llrender/llpostprocess.cpp
+++ b/indra/llrender/llpostprocess.cpp
@@ -35,6 +35,7 @@
#include "llpostprocess.h"
#include "lldir.h"
+#include "llcontrol.h"
#include "llfasttimer.h"
#include "llgl.h"
#include "llglslshader.h"
@@ -286,7 +287,7 @@ public:
LLVector2 screen_rect = LLPostProcess::getInstance()->getDimensions();
mPassLoc = getShader().getUniformLocation(sHorizontalPass);
- LLVector4 vec[] = { LLVector4(1.3846153846, 3.2307692308, 0, 0) / screen_rect.mV[VX], LLVector4( 0,0, 1.3846153846, 3.2307692308 ) / screen_rect.mV[VY] };
+ LLVector4 vec[] = { LLVector4(1.3846153846f, 3.2307692308f, 0.f, 0.f) / screen_rect.mV[VX], LLVector4( 0.f,0.f, 1.3846153846f, 3.2307692308f ) / screen_rect.mV[VY] };
getShader().uniform4fv(sKern, LL_ARRAY_SIZE(vec), (GLfloat*)vec);
return QUAD_NORMAL;
}
@@ -355,42 +356,44 @@ LLPostProcess::LLPostProcess(void) :
mShaders.push_back(new LLPosterizeShader());
/* Do nothing. Needs to be updated to use our current shader system, and to work with the move into llrender.*/
- std::string pathName(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight", XML_FILENAME));
- LL_DEBUGS("AppInit", "Shaders") << "Loading PostProcess Effects settings from " << pathName << LL_ENDL;
-
- llifstream effectsXML(pathName);
-
- if (effectsXML)
+ auto load_effects = [&](const std::string& pathName)
{
- LLPointer parser = new LLSDXMLParser();
+ LL_DEBUGS("AppInit", "Shaders") << "Loading PostProcess Effects settings from " << pathName << LL_ENDL;
+ llifstream effectsXML(pathName);
- parser->parse(effectsXML, mAllEffectInfo, LLSDSerialize::SIZE_UNLIMITED);
- }
+ if (effectsXML)
+ {
+ LLPointer parser = new LLSDXMLParser();
+ parser->parse(effectsXML, mAllEffectInfo, LLSDSerialize::SIZE_UNLIMITED);
+ }
+ };
+ load_effects(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight", XML_FILENAME));
+ load_effects(gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "windlight", XML_FILENAME));
- // Singu TODO: Make this configurable via settings
- if (!mAllEffectInfo.has("default"))
- mAllEffectInfo["default"] = LLSD::emptyMap();
+ auto setting = gSavedSettings.getControl("SinguPostProcessDefault");
+ setting->getSignal()->connect(std::bind(&LLPostProcess::setSelectedEffect, this, std::bind(&LLSD::asStringRef, std::placeholders::_2)));
+ const auto& str = setting->get().asStringRef();
+ if (!mAllEffectInfo.has(str))
+ mAllEffectInfo[str] = LLSD::emptyMap();
- LLSD& defaults = mAllEffectInfo["default"];
+ LLSD& defaults = mAllEffectInfo[str];
- for(std::list >::iterator it=mShaders.begin();it!=mShaders.end();++it)
+ // Add defaults for all missing effects
+ for(auto& shader : mShaders)
{
- LLSD shader_defaults = (*it)->getDefaults();
+ const LLSD shader_defaults = shader->getDefaults();
for (LLSD::map_const_iterator it2 = defaults.beginMap();it2 != defaults.endMap();++it2)
{
if(!defaults.has(it2->first))
defaults[it2->first]=it2->second;
}
}
- for(std::list >::iterator it=mShaders.begin();it!=mShaders.end();++it)
- {
- (*it)->loadSettings(defaults);
- }
- setSelectedEffect("default");
+ setSelectedEffect(str);
}
LLPostProcess::~LLPostProcess(void)
{
+ gSavedSettings.setString("SinguPostProcessDefault", mSelectedEffectName);
destroyGL() ;
}
@@ -663,10 +666,11 @@ void LLPostProcess::setSelectedEffect(std::string const & effectName)
{
mSelectedEffectName = effectName;
mSelectedEffectInfo = mAllEffectInfo[effectName];
- for(std::list >::iterator it=mShaders.begin();it!=mShaders.end();++it)
+ for(auto shader : mShaders)
{
- (*it)->loadSettings(mSelectedEffectInfo);
+ shader->loadSettings(mSelectedEffectInfo);
}
+ mSelectedEffectChanged(mSelectedEffectName);
}
void LLPostProcess::setSelectedEffectValue(std::string const & setting, LLSD value)
@@ -702,8 +706,9 @@ void LLPostProcess::resetSelectedEffect()
void LLPostProcess::saveEffectAs(std::string const & effectName)
{
mAllEffectInfo[effectName] = mSelectedEffectInfo;
+ mSelectedEffectChanged(mSelectedEffectName); // Might've changed, either way update the lists
- std::string pathName(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight", XML_FILENAME));
+ std::string pathName(gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "windlight", XML_FILENAME));
//LL_INFOS() << "Saving PostProcess Effects settings to " << pathName << LL_ENDL;
llofstream effectsXML(pathName);
diff --git a/indra/llrender/llpostprocess.h b/indra/llrender/llpostprocess.h
index 14ea2881d..b130cf2af 100644
--- a/indra/llrender/llpostprocess.h
+++ b/indra/llrender/llpostprocess.h
@@ -34,6 +34,7 @@
#define LL_POSTPROCESS_H
#include
+#include
#include "llsd.h"
#include "llrendertarget.h"
@@ -103,6 +104,9 @@ private:
// The map of all availible effects
LLSD mAllEffectInfo;
+ typedef boost::signals2::signal selected_effect_changed_signal;
+ selected_effect_changed_signal mSelectedEffectChanged;
+
public:
LLPostProcess(void);
~LLPostProcess(void);
@@ -144,6 +148,7 @@ public:
// Setters
void setSelectedEffect(std::string const & effectName);
void setSelectedEffectValue(std::string const & setting, LLSD value);
+ auto setSelectedEffectChangeCallback(const selected_effect_changed_signal::slot_type& func) { return mSelectedEffectChanged.connect(func); }
void resetSelectedEffect();
void saveEffectAs(std::string const & effectName);
};
diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp
index 9b5adf60c..568ec8c14 100644
--- a/indra/llrender/llshadermgr.cpp
+++ b/indra/llrender/llshadermgr.cpp
@@ -985,7 +985,7 @@ void LLShaderMgr::cleanupShaderSources()
for (GLsizei i = 0; i < count; ++i)
{
std::multimap::iterator it = mShaderObjects.begin();
- for (; it != LLShaderMgr::instance()->mShaderObjects.end(); it++)
+ for (; it != mShaderObjects.end(); it++)
{
if ((*it).second.mHandle == shaders[i])
{
diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt
index 1ee716cb8..b00081882 100644
--- a/indra/llui/CMakeLists.txt
+++ b/indra/llui/CMakeLists.txt
@@ -44,6 +44,7 @@ set(llui_SOURCE_FILES
llkeywords.cpp
lllayoutstack.cpp
lllineeditor.cpp
+ llloadingindicator.cpp
lllocalcliprect.cpp
llmenugl.cpp
llmodaldialog.cpp
@@ -122,6 +123,7 @@ set(llui_HEADER_FILES
llkeywords.h
lllayoutstack.h
lllineeditor.h
+ llloadingindicator.h
lllocalcliprect.h
llmemberlistener.h
llmenugl.h
diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp
index e8bf11a1d..60eae831c 100644
--- a/indra/llui/llbutton.cpp
+++ b/indra/llui/llbutton.cpp
@@ -61,66 +61,92 @@ S32 BTN_HEIGHT = 0;
S32 BTN_GRID = 12;
S32 BORDER_SIZE = 1;
+
+LLButton::Params::Params()
+ : label_selected("label_selected"), // requires is_toggle true
+ label_shadow("label_shadow", true),
+ auto_resize("auto_resize", false),
+ use_ellipses("use_ellipses", false),
+ image_unselected("image_unselected", LLUI::getUIImage("button_enabled_32x128.tga")),
+ image_selected("image_selected", LLUI::getUIImage("button_enabled_selected_32x128.tga")),
+ image_hover_selected("image_hover_selected"),
+ image_hover_unselected("image_hover_unselected"),
+ image_disabled_selected("image_disabled_selected", LLUI::getUIImage("button_disabled_32x128.tga")),
+ image_disabled("image_disabled", LLUI::getUIImage("button_disabled_32x128.tga")),
+ image_pressed("image_pressed", LLUI::getUIImage("button_enabled_selected_32x128.tga")),
+ image_pressed_selected("image_pressed_selected", LLUI::getUIImage("button_enabled_32x128.tga")),
+ image_overlay("image_overlay"),
+ image_overlay_selected("image_overlay_selected"),
+ image_overlay_alignment("image_overlay_alignment", std::string("center")),
+ image_overlay_enable("image_overlay_enable", true),
+ label_color("label_color", LLUI::sColorsGroup->getColor("ButtonLabelColor")),
+ label_color_selected("label_color_selected", LLUI::sColorsGroup->getColor("ButtonLabelSelectedColor")),
+ label_color_disabled("label_color_disabled", LLUI::sColorsGroup->getColor("ButtonLabelDisabledColor")),
+ label_color_disabled_selected("label_color_disabled_selected", LLUI::sColorsGroup->getColor("ButtonLabelSelectedDisabledColor")),
+ image_color("image_color", LLUI::sColorsGroup->getColor("ButtonImageColor")), // requires is_toggle true
+ image_color_disabled("image_color_disabled", LLUI::sColorsGroup->getColor("ButtonImageColor")),
+ image_overlay_color("image_overlay_color", LLColor4::white),
+ image_overlay_selected_color("image_overlay_selected_color", LLColor4::white),
+ image_overlay_disabled_color("image_overlay_disabled_color", LLColor4(1.f, 1.f, 1.f, .5f)),
+ flash_color("flash_color", LLUI::sColorsGroup->getColor("ButtonFlashBgColor")),
+ pad_right("pad_right", LLUI::sConfigGroup->getS32("ButtonHPad")),
+ pad_left("pad_left", LLUI::sConfigGroup->getS32("ButtonHPad")),
+ pad_bottom("pad_bottom", LLUI::sConfigGroup->getS32("ButtonVPad")),
+ image_top_pad("image_top_pad"),
+ image_bottom_pad("image_bottom_pad"),
+ imgoverlay_label_space("imgoverlay_label_space", 1),
+ click_callback("click_callback"),
+ mouse_down_callback("mouse_down_callback"),
+ mouse_up_callback("mouse_up_callback"),
+ mouse_held_callback("mouse_held_callback"),
+ is_toggle("is_toggle", false),
+ scale_image("scale_image", true),
+ commit_on_return("commit_on_return", true),
+ display_pressed_state("display_pressed_state", true),
+ hover_glow_amount("hover_glow_amount", 0.25f),
+ //held_down_delay("held_down_delay"),
+ use_draw_context_alpha("use_draw_context_alpha", true),
+ //badge("badge"),
+ handle_right_mouse("handle_right_mouse", false),
+ button_flash_enable("button_flash_enable", false),
+ button_flash_count("button_flash_count", LLUI::sConfigGroup->getS32("ButtonFlashCount")),
+ button_flash_rate("button_flash_rate", LLUI::sConfigGroup->getF32("ButtonFlashRate")),
+ fade_when_disabled("fade_when_disabled", false),
+ help_url("help_url")
+{
+ addSynonym(is_toggle, "toggle");
+ changeDefault(initial_value, LLSD(false));
+ changeDefault(font_halign, LLFontGL::HCENTER);
+}
+
LLButton::LLButton( const std::string& name, const LLRect& rect, const std::string& control_name, commit_callback_t commit_callback)
: LLUICtrl(name, rect, TRUE, commit_callback),
-
- mMouseDownFrame( 0 ),
+ mMouseDownFrame(0),
mMouseHeldDownCount(0),
- mBorderEnabled( FALSE ),
- mFlashing( FALSE ),
+ mBorderEnabled(FALSE),
+ mFlashing(FALSE),
mCurGlowStrength(0.f),
mNeedsHighlight(FALSE),
- mUnselectedLabel(name),
- mSelectedLabel(name),
- mGLFont( LLFontGL::getFontSansSerif() ),
- mHeldDownDelay( 0.5f ), // seconds until held-down callback is called
- mHeldDownFrameDelay( 0 ),
- mImageUnselected(LLUI::getUIImage("button_enabled_32x128.tga")),
- mImageSelected(LLUI::getUIImage("button_enabled_selected_32x128.tga")),
- mImageDisabled(LLUI::getUIImage("button_disabled_32x128.tga")),
- mImageDisabledSelected(LLUI::getUIImage("button_disabled_32x128.tga")),
- mImagePressed(LLUI::getUIImage("button_enabled_selected_32x128.tga")),
- mImagePressedSelected(LLUI::getUIImage("button_enabled_32x128.tga")),
+ mHeldDownDelay(0.5f), // seconds until held-down callback is called
+ mHeldDownFrameDelay(0),
mImageFlash(NULL),
- mImageHoverSelected( NULL ),
- mImageHoverUnselected( NULL ),
- mUnselectedLabelColor(LLUI::sColorsGroup->getColor("ButtonLabelColor" )),
- mSelectedLabelColor(LLUI::sColorsGroup->getColor("ButtonLabelSelectedColor")),
- mDisabledLabelColor(LLUI::sColorsGroup->getColor("ButtonLabelDisabledColor")),
- mDisabledSelectedLabelColor(LLUI::sColorsGroup->getColor("ButtonLabelSelectedDisabledColor")),
- mImageColor(LLUI::sColorsGroup->getColor("ButtonImageColor")),
- mFlashBgColor(LLUI::sColorsGroup->getColor("ButtonFlashBgColor")),
- mDisabledImageColor(LLUI::sColorsGroup->getColor("ButtonImageColor")),
- mImageOverlay(NULL),
- mImageOverlayColor(LLColor4::white),
- mImageOverlayDisabledColor(LLColor4(1.f,1.f,1.f,.5f)),
- mImageOverlaySelectedColor(LLColor4::white),
- mImageOverlayAlignment(LLFontGL::HCENTER),
mImageOverlayTopPad(0),
mImageOverlayBottomPad(0),
mImgOverlayLabelSpace(1),
- mIsToggle( FALSE ),
- mScaleImage( TRUE ),
- mDropShadowedText( TRUE ),
- mAutoResize( FALSE ),
- mHAlign( LLFontGL::HCENTER ),
- mLeftHPad( LLBUTTON_H_PAD ),
- mRightHPad( LLBUTTON_H_PAD ),
- mBottomVPad( LLBUTTON_V_PAD ),
- mHoverGlowStrength(0.25f),
- mCommitOnReturn(TRUE),
- mFadeWhenDisabled(FALSE),
+ mDropShadowedText(TRUE),
mForcePressedState(false),
- mDisplayPressedState(TRUE),
- mMouseDownSignal(NULL),
- mMouseUpSignal(NULL),
- mHeldDownSignal(NULL),
- mHandleRightMouse(false),
- mButtonFlashCount(LLUI::sConfigGroup->getS32("ButtonFlashCount")),
- mButtonFlashRate(LLUI::sConfigGroup->getF32("ButtonFlashRate")),
- mAlpha(1.f)
+ mAlpha(1.f),
+ mMouseDownSignal(nullptr),
+ mMouseUpSignal(nullptr),
+ mHeldDownSignal(nullptr)
{
- init(control_name);
+ Params params;
+ params.label_selected(name)
+ .label(name)
+ .control_name(control_name)
+ .name(name)
+ .rect(rect);
+ initFromParams(params);
}
@@ -133,92 +159,133 @@ LLButton::LLButton(const std::string& name, const LLRect& rect,
const std::string& unselected_label,
const std::string& selected_label )
: LLUICtrl(name, rect, TRUE, commit_callback),
- mMouseDownFrame( 0 ),
+ mMouseDownFrame(0),
mMouseHeldDownCount(0),
- mBorderEnabled( FALSE ),
- mFlashing( FALSE ),
+ mBorderEnabled(FALSE),
+ mFlashing(FALSE),
mCurGlowStrength(0.f),
mNeedsHighlight(FALSE),
- mUnselectedLabel(unselected_label),
- mSelectedLabel(selected_label),
- mGLFont( font ? font : LLFontGL::getFontSansSerif() ),
- mHeldDownDelay( 0.5f ), // seconds until held-down callback is called
- mHeldDownFrameDelay( 0 ),
- mImageUnselected(LLUI::getUIImage("button_enabled_32x128.tga")),
- mImageSelected(LLUI::getUIImage("button_enabled_selected_32x128.tga")),
- mImageDisabled(LLUI::getUIImage("button_disabled_32x128.tga")),
- mImageDisabledSelected(LLUI::getUIImage("button_disabled_32x128.tga")),
- mImagePressed(LLUI::getUIImage("button_enabled_selected_32x128.tga")),
- mImagePressedSelected(LLUI::getUIImage("button_enabled_32x128.tga")),
+ mHeldDownDelay(0.5f), // seconds until held-down callback is called
+ mHeldDownFrameDelay(0),
mImageFlash(NULL),
- mImageHoverSelected( NULL ),
- mImageHoverUnselected( NULL ),
- mUnselectedLabelColor(LLUI::sColorsGroup->getColor("ButtonLabelColor" )),
- mSelectedLabelColor(LLUI::sColorsGroup->getColor("ButtonLabelSelectedColor")),
- mDisabledLabelColor(LLUI::sColorsGroup->getColor("ButtonLabelDisabledColor")),
- mDisabledSelectedLabelColor(LLUI::sColorsGroup->getColor("ButtonLabelSelectedDisabledColor")),
- mImageColor(LLUI::sColorsGroup->getColor("ButtonImageColor")),
- mFlashBgColor(LLUI::sColorsGroup->getColor("ButtonFlashBgColor")),
- mDisabledImageColor(LLUI::sColorsGroup->getColor("ButtonImageColor")),
- mImageOverlay(NULL),
- mImageOverlayColor(LLColor4::white),
- mImageOverlayDisabledColor(LLColor4(1.f,1.f,1.f,.5f)),
- mImageOverlaySelectedColor(LLColor4::white),
- mImageOverlayAlignment(LLFontGL::HCENTER),
mImageOverlayTopPad(0),
mImageOverlayBottomPad(0),
mImgOverlayLabelSpace(1),
- mIsToggle( FALSE ),
- mScaleImage( TRUE ),
- mDropShadowedText( TRUE ),
- mAutoResize( FALSE ),
- mHAlign( LLFontGL::HCENTER ),
- mLeftHPad( LLBUTTON_H_PAD ),
- mRightHPad( LLBUTTON_H_PAD ),
- mBottomVPad( LLBUTTON_V_PAD ),
- mHoverGlowStrength(0.25f),
- mCommitOnReturn(TRUE),
- mFadeWhenDisabled(FALSE),
+ mDropShadowedText(TRUE),
mForcePressedState(false),
- mDisplayPressedState(TRUE),
- mMouseDownSignal(NULL),
- mMouseUpSignal(NULL),
- mHeldDownSignal(NULL),
- mHandleRightMouse(false),
- mButtonFlashCount(LLUI::sConfigGroup->getS32("ButtonFlashCount")),
- mButtonFlashRate(LLUI::sConfigGroup->getF32("ButtonFlashRate")),
- mAlpha(1.f)
+ mAlpha(1.f),
+ mMouseDownSignal(nullptr),
+ mMouseUpSignal(nullptr),
+ mHeldDownSignal(nullptr)
{
+ Params params;
+ params.label_selected(selected_label)
+ .label(unselected_label)
+ .font(font)
+ .control_name(control_name)
+ .name(name)
+ .rect(rect);
- if( unselected_image_name != "" )
+ if (!unselected_image_name.empty())
{
// user-specified image - don't use fixed borders unless requested
- mImageUnselected = LLUI::getUIImage(unselected_image_name);
- mImageDisabled = mImageUnselected;
+ auto image = LLUI::getUIImage(unselected_image_name);
+ params.image_unselected(image)
+ .image_disabled(image)
+ .image_pressed_selected(image)
- mFadeWhenDisabled = TRUE;
- //mScaleImage = FALSE;
-
- mImagePressedSelected = mImageUnselected;
+ .fade_when_disabled(true);
+ //params.scale_image(false);
}
- if( selected_image_name != "" )
+ if (!selected_image_name.empty())
{
// user-specified image - don't use fixed borders unless requested
- mImageSelected = LLUI::getUIImage(selected_image_name);
- mImageDisabledSelected = mImageSelected;
+ auto image = LLUI::getUIImage(selected_image_name);
+ params.image_selected(image)
+ .image_disabled_selected(image)
+ .image_pressed(image)
- mFadeWhenDisabled = TRUE;
- //mScaleImage = FALSE;
-
- mImagePressed = mImageSelected;
+ .fade_when_disabled(true);
+ //params.scale_image(false);
}
- init(control_name);
+ initFromParams(params);
}
-void LLButton::init(const std::string& control_name)
+LLButton::LLButton(const Params& params)
+: LLUICtrl(params),
+ mMouseDownFrame(0),
+ mMouseHeldDownCount(0),
+ mBorderEnabled(FALSE),
+ mFlashing(FALSE),
+ mCurGlowStrength(0.f),
+ mNeedsHighlight(FALSE),
+ mHeldDownDelay(0.5f), // seconds until held-down callback is called
+ mHeldDownFrameDelay(0),
+ mImageFlash(NULL),
+ mImageOverlayTopPad(0),
+ mImageOverlayBottomPad(0),
+ mImgOverlayLabelSpace(1),
+ mDropShadowedText(TRUE),
+ mForcePressedState(false),
+ mAlpha(1.f),
+ mMouseDownSignal(nullptr),
+ mMouseUpSignal(nullptr),
+ mHeldDownSignal(nullptr)
{
+ initFromParams(params);
+}
+
+void LLButton::initFromParams(const Params& params)
+{
+ LLUICtrl::initFromParams(params);
+ mUnselectedLabel = params.label;
+ mSelectedLabel = params.label_selected;
+ auto font = params.font();
+ mGLFont = font ? font : LLFontGL::getFontSansSerif();
+ mHAlign = params.font_halign;
+ mImageUnselected = params.image_unselected;
+ mImageSelected = params.image_selected;
+ mImageDisabled = params.image_disabled;
+ mImageDisabledSelected = params.image_disabled_selected;
+ mImagePressed = params.image_pressed;
+ mImagePressedSelected = params.image_pressed_selected;
+ mImageHoverSelected = params.image_hover_selected;
+ mImageHoverUnselected = params.image_hover_unselected;
+ mUnselectedLabelColor = params.label_color;
+ mSelectedLabelColor = params.label_color_selected;
+ mDisabledLabelColor = params.label_color_disabled;
+ mDisabledSelectedLabelColor = params.label_color_disabled_selected;
+ mImageColor = params.image_color;
+ mFlashBgColor = params.flash_color;
+ mDisabledImageColor = params.image_color_disabled;
+ mImageOverlay = params.image_overlay;
+ mImageOverlaySelected = params.image_overlay_selected;
+ mImageOverlayColor = params.image_overlay_color;
+ mImageOverlayDisabledColor = params.image_overlay_disabled_color;
+ mImageOverlaySelectedColor = params.image_overlay_selected_color;
+ mImageOverlayAlignment = LLFontGL::hAlignFromName(params.image_overlay_alignment);
+ mIsToggle = params.is_toggle;
+ mScaleImage = params.scale_image;
+ mAutoResize = params.auto_resize;
+ mLeftHPad = params.pad_left;
+ mRightHPad = params.pad_right;
+ mBottomVPad = params.pad_bottom;
+ mHoverGlowStrength = params.hover_glow_amount;
+ mCommitOnReturn = params.commit_on_return;
+ mFadeWhenDisabled = params.fade_when_disabled;
+ mDisplayPressedState = params.display_pressed_state;
+ if (params.mouse_down_callback.isProvided())
+ setMouseDownCallback(params.mouse_down_callback);
+ if (params.mouse_up_callback.isProvided())
+ setMouseUpCallback(params.mouse_up_callback);
+ if (params.mouse_held_callback.isProvided())
+ setHeldDownCallback(params.mouse_held_callback);
+ mHandleRightMouse = params.handle_right_mouse;
+ mButtonFlashCount = params.button_flash_count;
+ mButtonFlashRate = params.button_flash_rate;
+
// Hack to make sure there is space for at least one character
if (getRect().getWidth() - (mRightHPad + mLeftHPad) < mGLFont->getWidth(std::string(" ")))
{
@@ -229,9 +296,16 @@ void LLButton::init(const std::string& control_name)
mMouseDownTimer.stop();
- setControlName(control_name, NULL);
+ setControlName(params.control_name, NULL);
}
+//static
+const LLButton::Params& LLButton::getDefaultParams()
+{
+ // Singu Note: We diverge here, not using LLUICtrlFactory::getDefaultParams
+ static const Params p;
+ return p;
+}
// virtual
LLButton::~LLButton()
@@ -783,12 +857,13 @@ void LLButton::draw()
}
overlay_color.mV[VALPHA] *= alpha;
+ auto& overlay = (mIsToggle && mImageOverlaySelected && getToggleState()) ? mImageOverlaySelected : mImageOverlay;
switch(mImageOverlayAlignment)
{
case LLFontGL::LEFT:
text_left += overlay_width + mImgOverlayLabelSpace;
text_width -= overlay_width + mImgOverlayLabelSpace;
- mImageOverlay->draw(
+ overlay->draw(
mLeftHPad,
center_y - (overlay_height / 2),
overlay_width,
@@ -796,7 +871,7 @@ void LLButton::draw()
overlay_color);
break;
case LLFontGL::HCENTER:
- mImageOverlay->draw(
+ overlay->draw(
center_x - (overlay_width / 2),
center_y - (overlay_height / 2),
overlay_width,
@@ -806,7 +881,7 @@ void LLButton::draw()
case LLFontGL::RIGHT:
text_right -= overlay_width + mImgOverlayLabelSpace;
text_width -= overlay_width + mImgOverlayLabelSpace;
- mImageOverlay->draw(
+ overlay->draw(
getRect().getWidth() - mRightHPad - overlay_width,
center_y - (overlay_height / 2),
overlay_width,
@@ -1199,6 +1274,9 @@ LLView* LLButton::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *fa
std::string image_overlay;
node->getAttributeString("image_overlay", image_overlay);
+ std::string image_overlay_selected;
+ node->getAttributeString("image_overlay_selected", image_overlay_selected);
+
LLFontGL::HAlign image_overlay_alignment = LLFontGL::HCENTER;
std::string image_overlay_alignment_string;
if (node->hasAttribute("image_overlay_alignment"))
@@ -1234,6 +1312,7 @@ LLView* LLButton::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *fa
if(image_disabled != LLStringUtil::null) button->setImageDisabled(LLUI::getUIImage(image_disabled));
if(image_overlay != LLStringUtil::null) button->setImageOverlay(image_overlay, image_overlay_alignment);
+ if (!image_overlay_selected.empty()) button->mImageOverlaySelected = LLUI::getUIImage(image_overlay_selected);
if (node->hasAttribute("halign"))
{
diff --git a/indra/llui/llbutton.h b/indra/llui/llbutton.h
index 1495740c6..812ea6de1 100644
--- a/indra/llui/llbutton.h
+++ b/indra/llui/llbutton.h
@@ -74,6 +74,87 @@ class LLButton
: public LLUICtrl
{
public:
+ struct Params
+ : public LLInitParam::Block
+ {
+ // text label
+ Optional label_selected;
+ Optional label_shadow;
+ Optional auto_resize;
+ Optional use_ellipses;
+
+ // images
+ Optional image_unselected,
+ image_selected,
+ image_hover_selected,
+ image_hover_unselected,
+ image_disabled_selected,
+ image_disabled,
+ image_flash,
+ image_pressed,
+ image_pressed_selected,
+ image_overlay,
+ image_overlay_selected;
+
+ Optional image_overlay_alignment;
+ Optional image_overlay_enable;
+
+ // colors
+ Optional label_color,
+ label_color_selected,
+ label_color_disabled,
+ label_color_disabled_selected,
+ image_color,
+ image_color_disabled,
+ image_overlay_color,
+ image_overlay_selected_color,
+ image_overlay_disabled_color,
+ flash_color;
+
+ // layout
+ Optional pad_right;
+ Optional pad_left;
+ Optional pad_bottom; // under text label
+
+ //image overlay paddings
+ Optional image_top_pad;
+ Optional image_bottom_pad;
+
+ /**
+ * Space between image_overlay and label
+ */
+ Optional imgoverlay_label_space;
+
+ // callbacks
+ Optional click_callback, // alias -> commit_callback
+ mouse_down_callback,
+ mouse_up_callback,
+ mouse_held_callback;
+
+ // misc
+ Optional is_toggle,
+ scale_image,
+ commit_on_return,
+ display_pressed_state;
+
+ Optional hover_glow_amount;
+ //Optional held_down_delay;
+
+ Optional use_draw_context_alpha;
+
+ //Optional badge;
+
+ Optional handle_right_mouse;
+
+ Optional button_flash_enable;
+ Optional button_flash_count;
+ Optional button_flash_rate;
+ Optional fade_when_disabled;
+ Optional help_url;
+
+ Params();
+ };
+
// simple button with text label
LLButton(const std::string& name, const LLRect &rect = LLRect(), const std::string& control_name = std::string(),
commit_callback_t commit_callback = NULL);
@@ -86,6 +167,11 @@ public:
const LLFontGL* mGLFont = NULL,
const std::string& unselected_label = LLStringUtil::null,
const std::string& selected_label = LLStringUtil::null );
+
+ void initFromParams(const Params& p);
+ static const LLButton::Params& getDefaultParams();
+ LLButton(const Params& p = getDefaultParams());
+
public:
~LLButton();
@@ -93,7 +179,6 @@ public:
typedef boost::function button_callback_t;
void addImageAttributeToXML(LLXMLNodePtr node, const LLPointer, const std::string& xmlTagName) const;
- void init(const std::string& control_name);
virtual LLXMLNodePtr getXML(bool save_children = true) const;
static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
@@ -161,7 +246,6 @@ public:
const std::string getLabelUnselected() const { return wstring_to_utf8str(mUnselectedLabel); }
const std::string getLabelSelected() const { return wstring_to_utf8str(mSelectedLabel); }
- void setImageColor(const std::string& color_control);
void setImageColor(const LLColor4& c);
/*virtual*/ void setColor(const LLColor4& c);
@@ -205,9 +289,7 @@ public:
void setImageDisabled(LLPointer image);
void setImageDisabledSelected(LLPointer image);
void setImageFlash(LLPointer image);
- void setImagePressed(LLPointer image);
-
- static void onHeldDown(void *userdata); // to be called by gIdleCallbacks
+
void setHelpURLCallback(const std::string &help_url);
const std::string& getHelpURL() const { return mHelpURL; }
@@ -243,6 +325,7 @@ protected:
S32 mHeldDownFrameDelay; // frames, after which held-down callbacks get called
LLPointer mImageOverlay;
+ LLPointer mImageOverlaySelected;
LLFontGL::HAlign mImageOverlayAlignment;
LLUIColor mImageOverlayColor;
LLUIColor mImageOverlaySelectedColor;
diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp
index 65a03b0b5..7a5141da2 100644
--- a/indra/llui/llcombobox.cpp
+++ b/indra/llui/llcombobox.cpp
@@ -436,6 +436,7 @@ void LLComboBox::setLabel(const LLStringExplicit& name)
{
if (!mSuppressTentative) mTextEntry->setTentative(mTextEntryTentative);
}
+ mTextEntry->setCursor(0); // Be scrolled to the beginning!
}
if (!mAllowTextEntry)
diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index dac5a0282..f5fa3ece2 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -35,8 +35,6 @@
#include "linden_common.h"
-#include "llmultifloater.h"
-
#include "llfocusmgr.h"
#include "lluictrlfactory.h"
@@ -56,10 +54,13 @@
#include "llcontrol.h"
#include "lltabcontainer.h"
#include "v2math.h"
+#include "lltrans.h"
+#include "llmultifloater.h"
#include "llfasttimer.h"
#include "airecursive.h"
#include "llnotifications.h"
+
const S32 MINIMIZED_WIDTH = 160;
const S32 CLOSE_BOX_FROM_TOP = 1;
// use this to control "jumping" behavior when Ctrl-Tabbing
@@ -104,14 +105,14 @@ std::string LLFloater::sButtonNames[BUTTON_COUNT] =
std::string LLFloater::sButtonToolTips[BUTTON_COUNT] =
{
#ifdef LL_DARWIN
- "Close (Cmd-W)", //BUTTON_CLOSE
+ "BUTTON_CLOSE_DARWIN", //"Close (Cmd-W)", //BUTTON_CLOSE
#else
- "Close (Ctrl-W)", //BUTTON_CLOSE
+ "BUTTON_CLOSE_WIN", //"Close (Ctrl-W)", //BUTTON_CLOSE
#endif
- "Restore", //BUTTON_RESTORE
- "Minimize", //BUTTON_MINIMIZE
- "Tear Off", //BUTTON_TEAR_OFF
- "Edit", //BUTTON_EDIT
+ "BUTTON_RESTORE", //"Restore", //BUTTON_RESTORE
+ "BUTTON_MINIMIZE", //"Minimize", //BUTTON_MINIMIZE
+ "BUTTON_TEAR_OFF", //"Tear Off", //BUTTON_TEAR_OFF
+ "BUTTON_EDIT", //"Edit", //BUTTON_EDIT
};
@@ -130,6 +131,31 @@ LLFloater::handle_map_t LLFloater::sFloaterMap;
LLFloaterView* gFloaterView = NULL;
+//static
+void LLFloater::initClass()
+{
+ // translate tooltips for floater buttons
+ for (S32 i = 0; i < BUTTON_COUNT; i++)
+ {
+ sButtonToolTips[i] = LLTrans::getString( sButtonToolTips[i] );
+ }
+
+ LLControlVariable* ctrl = LLUI::sConfigGroup->getControl("ActiveFloaterTransparency");
+ if (ctrl)
+ {
+ ctrl->getSignal()->connect(boost::bind(&LLFloater::updateActiveFloaterTransparency));
+ updateActiveFloaterTransparency();
+ }
+
+ ctrl = LLUI::sConfigGroup->getControl("InactiveFloaterTransparency");
+ if (ctrl)
+ {
+ ctrl->getSignal()->connect(boost::bind(&LLFloater::updateInactiveFloaterTransparency));
+ updateInactiveFloaterTransparency();
+ }
+
+}
+
LLFloater::LLFloater() :
//FIXME: we should initialize *all* member variables here
LLPanel(), mAutoFocus(TRUE),
@@ -355,6 +381,18 @@ void LLFloater::initFloater(const std::string& title,
}
}
+// static
+void LLFloater::updateActiveFloaterTransparency()
+{
+ sActiveControlTransparency = LLUI::sConfigGroup->getF32("ActiveFloaterTransparency");
+}
+
+// static
+void LLFloater::updateInactiveFloaterTransparency()
+{
+ sInactiveControlTransparency = LLUI::sConfigGroup->getF32("InactiveFloaterTransparency");
+}
+
void LLFloater::addResizeCtrls()
{
// Resize bars (sides)
@@ -720,11 +758,6 @@ void LLFloater::applyRectControl()
void LLFloater::applyTitle()
{
- if (gNoRender)
- {
- return;
- }
-
if (!mDragHandle)
{
return;
@@ -753,7 +786,7 @@ void LLFloater::setTitle( const std::string& title )
applyTitle();
}
-std::string LLFloater::getTitle()
+std::string LLFloater::getTitle() const
{
if (mTitle.empty())
{
@@ -771,7 +804,7 @@ void LLFloater::setShortTitle( const std::string& short_title )
applyTitle();
}
-std::string LLFloater::getShortTitle()
+std::string LLFloater::getShortTitle() const
{
if (mShortTitle.empty())
{
@@ -783,8 +816,6 @@ std::string LLFloater::getShortTitle()
}
}
-
-
BOOL LLFloater::canSnapTo(const LLView* other_view)
{
if (NULL == other_view)
@@ -1023,7 +1054,8 @@ void LLFloater::setFocus( BOOL b )
if (b)
{
// only push focused floaters to front of stack if not in midst of ctrl-tab cycle
- if (!getHost() && !((LLFloaterView*)getParent())->getCycleMode())
+ LLFloaterView * parent = dynamic_cast(getParent());
+ if (!getHost() && parent && !parent->getCycleMode())
{
if (!isFrontmost())
{
@@ -1040,6 +1072,7 @@ void LLFloater::setFocus( BOOL b )
last_focus->setFocus(TRUE);
}
}
+ updateTransparency(b ? TT_ACTIVE : TT_INACTIVE);
}
// virtual
@@ -1081,8 +1114,9 @@ void LLFloater::setForeground(BOOL front)
releaseFocus();
}
- if (front || !LLUI::sConfigGroup->getBOOL("FloaterUnfocusedBackgroundOpaque")) // Singu Note: This can be removed when InactiveFloaterTransparency is added
- setBackgroundOpaque( front );
+ setBackgroundOpaque( front );
+ // Singu Note: Upstream isn't doing this, I can't see where they were actually going inactive. Maybe setFocus(false) isn't being called, but we have parity there..
+ updateTransparency(front || getIsChrome() ? TT_ACTIVE : TT_INACTIVE);
}
}
@@ -1191,7 +1225,7 @@ void LLFloater::removeDependentFloater(LLFloater* floaterp)
floaterp->mDependeeHandle = LLHandle();
}
-BOOL LLFloater::offerClickToButton(S32 x, S32 y, MASK mask, EFloaterButtons index)
+BOOL LLFloater::offerClickToButton(S32 x, S32 y, MASK mask, EFloaterButton index)
{
if( mButtonsEnabled[index] )
{
@@ -1297,7 +1331,14 @@ void LLFloater::setFrontmost(BOOL take_focus)
{
// there are more than one floater view
// so we need to query our parent directly
- ((LLFloaterView*)getParent())->bringToFront(this, take_focus);
+ LLFloaterView * parent = dynamic_cast( getParent() );
+ if (parent)
+ {
+ parent->bringToFront(this, take_focus);
+ }
+
+ // Make sure to set the appropriate transparency type (STORM-732).
+ updateTransparency(hasFocus() || getIsChrome() ? TT_ACTIVE : TT_INACTIVE);
}
}
@@ -1432,42 +1473,45 @@ void LLFloater::onClickClose()
// virtual
void LLFloater::draw()
{
+ const F32 alpha = getCurrentTransparency();
+
// draw background
if( isBackgroundVisible() )
{
+ drawShadow(this);
+
S32 left = LLPANEL_BORDER_WIDTH;
S32 top = getRect().getHeight() - LLPANEL_BORDER_WIDTH;
S32 right = getRect().getWidth() - LLPANEL_BORDER_WIDTH;
S32 bottom = LLPANEL_BORDER_WIDTH;
- static LLColor4 shadow_color = LLUI::sColorsGroup->getColor("ColorDropShadow");
- static F32 shadow_offset = (F32)LLUI::sConfigGroup->getS32("DropShadowFloater");
- if (!isBackgroundOpaque())
- {
- shadow_offset *= 0.2f;
- shadow_color.mV[VALPHA] *= 0.5f;
- }
- gl_drop_shadow(left, top, right, bottom,
- shadow_color,
- ll_round(shadow_offset));
-
// No transparent windows in simple UI
+ LLColor4 color;
if (isBackgroundOpaque())
{
- gl_rect_2d( left, top, right, bottom, getBackgroundColor() );
+ color = getBackgroundColor();
}
else
{
- gl_rect_2d( left, top, right, bottom, getTransparentColor() );
+ color = getTransparentColor();
}
- if(gFocusMgr.childHasKeyboardFocus(this) && !getIsChrome() && !getCurrentTitle().empty())
{
+ // We're not using images, use old-school flat colors
+ gl_rect_2d( left, top, right, bottom, color % alpha );
+
// draw highlight on title bar to indicate focus. RDW
- const LLFontGL* font = LLResMgr::getInstance()->getRes( LLFONT_SANSSERIF );
- LLRect r = getRect();
- gl_rect_2d_offset_local(0, r.getHeight(), r.getWidth(), r.getHeight() - (S32)font->getLineHeight() - 1,
- LLUI::sColorsGroup->getColor("TitleBarFocusColor"), 0, TRUE);
+ if(gFocusMgr.childHasKeyboardFocus(this)
+ && !getIsChrome()
+ && !getCurrentTitle().empty())
+ {
+ static auto titlebar_focus_color = LLUI::sColorsGroup->getColor("TitleBarFocusColor");
+
+ const LLFontGL* font = LLFontGL::getFontSansSerif();
+ LLRect r = getRect();
+ gl_rect_2d_offset_local(0, r.getHeight(), r.getWidth(), r.getHeight() - (S32)font->getLineHeight() - 1,
+ titlebar_focus_color % alpha, 0, TRUE);
+ }
}
}
@@ -1524,6 +1568,49 @@ void LLFloater::draw()
}
}
+void LLFloater::drawShadow(LLPanel* panel)
+{
+ S32 left = LLPANEL_BORDER_WIDTH;
+ S32 top = panel->getRect().getHeight() - LLPANEL_BORDER_WIDTH;
+ S32 right = panel->getRect().getWidth() - LLPANEL_BORDER_WIDTH;
+ S32 bottom = LLPANEL_BORDER_WIDTH;
+
+ static LLUICachedControl shadow_offset_S32 ("DropShadowFloater", 0);
+ static LLColor4 shadow_color = LLUI::sColorsGroup->getColor("ColorDropShadow");
+ F32 shadow_offset = (F32)shadow_offset_S32;
+
+ if (!panel->isBackgroundOpaque())
+ {
+ shadow_offset *= 0.2f;
+ shadow_color.mV[VALPHA] *= 0.5f;
+ }
+ gl_drop_shadow(left, top, right, bottom,
+ shadow_color % getCurrentTransparency(),
+ ll_round(shadow_offset));
+}
+
+void LLFloater::updateTransparency(LLView* view, ETypeTransparency transparency_type)
+{
+ if (view)
+ {
+ if (view->isCtrl())
+ {
+ static_cast(view)->setTransparencyType(transparency_type);
+ }
+
+ for (LLView* pChild : *view->getChildList())
+ {
+ if ((pChild->getChildCount()) || (pChild->isCtrl()))
+ updateTransparency(pChild, transparency_type);
+ }
+ }
+}
+
+void LLFloater::updateTransparency(ETypeTransparency transparency_type)
+{
+ updateTransparency(this, transparency_type);
+}
+
void LLFloater::setCanMinimize(BOOL can_minimize)
{
// if removing minimize/restore button programmatically,
@@ -2319,7 +2406,7 @@ LLRect LLFloaterView::getSnapRect() const
return snap_rect;
}
-LLFloater *LLFloaterView::getFocusedFloater()
+LLFloater *LLFloaterView::getFocusedFloater() const
{
for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it)
{
@@ -2332,7 +2419,7 @@ LLFloater *LLFloaterView::getFocusedFloater()
return NULL;
}
-LLFloater *LLFloaterView::getFrontmost()
+LLFloater *LLFloaterView::getFrontmost() const
{
for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it)
{
@@ -2345,7 +2432,7 @@ LLFloater *LLFloaterView::getFrontmost()
return NULL;
}
-LLFloater *LLFloaterView::getBackmost()
+LLFloater *LLFloaterView::getBackmost() const
{
LLFloater* back_most = NULL;
for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it)
@@ -2380,7 +2467,7 @@ void LLFloaterView::syncFloaterTabOrder()
}
}
-LLFloater* LLFloaterView::getParentFloater(LLView* viewp)
+LLFloater* LLFloaterView::getParentFloater(LLView* viewp) const
{
LLView* parentp = viewp->getParent();
diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h
index 0aeb11501..f53e2714f 100644
--- a/indra/llui/llfloater.h
+++ b/indra/llui/llfloater.h
@@ -94,16 +94,19 @@ class LLFloater : public LLPanel
friend class LLFloaterView;
friend class LLMultiFloater;
public:
- enum EFloaterButtons
+ enum EFloaterButton
{
- BUTTON_CLOSE,
+ BUTTON_CLOSE = 0,
BUTTON_RESTORE,
BUTTON_MINIMIZE,
BUTTON_TEAR_OFF,
BUTTON_EDIT,
BUTTON_COUNT
};
-
+
+ // Load translations for tooltips for standard buttons
+ static void initClass();
+
LLFloater();
LLFloater(const std::string& name); //simple constructor for data-driven initialization
LLFloater( const std::string& name, const LLRect& rect, const std::string& title,
@@ -164,9 +167,9 @@ public:
void applyTitle();
const std::string& getCurrentTitle() const;
void setTitle( const std::string& title);
- std::string getTitle();
+ std::string getTitle() const;
void setShortTitle( const std::string& short_title );
- std::string getShortTitle();
+ std::string getShortTitle() const;
void setTitleVisible(bool visible);
virtual void setMinimized(BOOL b);
void moveResizeHandlesToFront();
@@ -174,8 +177,8 @@ public:
void addDependentFloater(LLHandle dependent_handle, BOOL reposition = TRUE);
LLFloater* getDependee() { return (LLFloater*)mDependeeHandle.get(); }
void removeDependentFloater(LLFloater* dependent);
- BOOL isMinimized() { return mMinimized; }
- BOOL isFrontmost();
+ BOOL isMinimized() const { return mMinimized; }
+ virtual BOOL isFrontmost();
BOOL isDependent() { return !mDependeeHandle.isDead(); }
void setCanMinimize(BOOL can_minimize);
void setCanClose(BOOL can_close);
@@ -199,6 +202,7 @@ public:
virtual BOOL handleDoubleClick(S32 x, S32 y, MASK mask);
virtual BOOL handleMiddleMouseDown(S32 x, S32 y, MASK mask);
virtual void draw();
+ virtual void drawShadow(LLPanel* panel);
virtual void onOpen() {}
@@ -244,6 +248,8 @@ public:
static BOOL getEditModeEnabled() { return sEditModeEnabled; }
static LLMultiFloater* getFloaterHost() {return sHostp; }
+ void updateTransparency(ETypeTransparency transparency_type);
+
void enableResizeCtrls(bool enable, bool width = true, bool height = true);
protected:
@@ -259,21 +265,29 @@ protected:
void destroy() { die(); } // Don't call this directly. You probably want to call close(). JC
private:
-
void setForeground(BOOL b); // called only by floaterview
void cleanupHandles(); // remove handles to dead floaters
void createMinimizeButton();
void updateButtons();
void buildButtons();
- BOOL offerClickToButton(S32 x, S32 y, MASK mask, EFloaterButtons index);
+ BOOL offerClickToButton(S32 x, S32 y, MASK mask, EFloaterButton index);
void addResizeCtrls();
void layoutResizeCtrls();
+ static void updateActiveFloaterTransparency();
+ static void updateInactiveFloaterTransparency();
+ void updateTransparency(LLView* view, ETypeTransparency transparency_type);
+
LLRect mExpandedRect;
+
+protected:
LLDragHandle* mDragHandle;
LLResizeBar* mResizeBar[4];
LLResizeHandle* mResizeHandle[4];
LLButton *mMinimizeButton;
+
+ LLButton* mButtons[BUTTON_COUNT];
+private:
BOOL mCanTearOff;
BOOL mMinimized;
BOOL mForeground;
@@ -294,10 +308,7 @@ private:
handle_set_t mDependents;
bool mDragOnLeft;
- BOOL mButtonsEnabled[BUTTON_COUNT];
-protected:
- LLButton* mButtons[BUTTON_COUNT];
-private:
+ bool mButtonsEnabled[BUTTON_COUNT];
F32 mButtonScale;
BOOL mAutoFocus;
LLHandle mSnappedTo;
@@ -344,7 +355,7 @@ public:
/*virtual*/ void draw();
/*virtual*/ LLRect getSnapRect() const;
- void refresh();
+ /*virtual*/ void refresh();
void getNewFloaterPosition( S32* left, S32* top );
void resetStartingFloaterPosition();
@@ -373,10 +384,10 @@ public:
void minimizeAllChildren();
//
- LLFloater* getFrontmost();
- LLFloater* getBackmost();
- LLFloater* getParentFloater(LLView* viewp);
- LLFloater* getFocusedFloater();
+ LLFloater* getFrontmost() const;
+ LLFloater* getBackmost() const;
+ LLFloater* getParentFloater(LLView* viewp) const;
+ LLFloater* getFocusedFloater() const;
void syncFloaterTabOrder();
// Returns z order of child provided. 0 is closest, larger numbers
diff --git a/indra/llui/llfocusmgr.cpp b/indra/llui/llfocusmgr.cpp
index 1be8be2b0..60983c9d4 100644
--- a/indra/llui/llfocusmgr.cpp
+++ b/indra/llui/llfocusmgr.cpp
@@ -33,10 +33,10 @@
const F32 FOCUS_FADE_TIME = 0.3f;
LLFocusableElement::LLFocusableElement()
-: mFocusLostCallback(NULL),
- mFocusReceivedCallback(NULL),
- mFocusChangedCallback(NULL),
- mTopLostCallback(NULL)
+: mFocusLostCallback(nullptr),
+ mFocusReceivedCallback(nullptr),
+ mFocusChangedCallback(nullptr),
+ mTopLostCallback(nullptr)
{
}
@@ -146,14 +146,14 @@ struct LLFocusMgr::Impl
LLFocusMgr gFocusMgr;
LLFocusMgr::LLFocusMgr()
-: mLockedView( NULL ),
- mMouseCaptor( NULL ),
- mKeyboardFocus( NULL ),
- mLastKeyboardFocus( NULL ),
- mDefaultKeyboardFocus( NULL ),
- mLastDefaultKeyboardFocus( NULL ),
+: mLockedView(nullptr ),
+ mMouseCaptor(nullptr ),
+ mKeyboardFocus(nullptr ),
+ mLastKeyboardFocus(nullptr ),
+ mDefaultKeyboardFocus(nullptr ),
+ mLastDefaultKeyboardFocus(nullptr ),
mKeystrokesOnly(FALSE),
- mTopCtrl( NULL ),
+ mTopCtrl(nullptr ),
mAppHasFocus(TRUE), // Macs don't seem to notify us that we've gotten focus, so default to true
mImpl(new LLFocusMgr::Impl)
{
@@ -163,22 +163,22 @@ LLFocusMgr::~LLFocusMgr()
{
mImpl->mFocusHistory.clear();
delete mImpl;
- mImpl = NULL;
+ mImpl = nullptr;
}
void LLFocusMgr::releaseFocusIfNeeded( const LLView* view )
{
if( childHasMouseCapture( view ) )
{
- setMouseCapture( NULL );
+ setMouseCapture(nullptr );
}
if( childHasKeyboardFocus( view ))
{
if (view == mLockedView)
{
- mLockedView = NULL;
- setKeyboardFocus( NULL );
+ mLockedView = nullptr;
+ setKeyboardFocus(nullptr );
}
else
{
@@ -188,7 +188,7 @@ void LLFocusMgr::releaseFocusIfNeeded( const LLView* view )
if( childIsTopCtrl( view ) )
{
- setTopCtrl( NULL );
+ setTopCtrl(nullptr);
}
}
@@ -197,7 +197,7 @@ void LLFocusMgr::restoreDefaultKeyboardFocus(LLFocusableElement* current_default
if (current_default_focus && mDefaultKeyboardFocus == current_default_focus)
{
setDefaultKeyboardFocus(mLastDefaultKeyboardFocus);
- mLastDefaultKeyboardFocus = NULL;
+ mLastDefaultKeyboardFocus = nullptr;
}
}
@@ -206,7 +206,7 @@ void LLFocusMgr::restoreKeyboardFocus(LLFocusableElement* current_focus)
if (current_focus && mKeyboardFocus == current_focus)
{
setKeyboardFocus(mLastKeyboardFocus);
- mLastKeyboardFocus = NULL;
+ mLastKeyboardFocus = nullptr;
}
}
@@ -219,7 +219,7 @@ void LLFocusMgr::setKeyboardFocus(LLFocusableElement* new_focus, BOOL lock, BOOL
focus_dirty = false;
if (mLockedView &&
- (new_focus == NULL ||
+ (new_focus == nullptr ||
(new_focus != mLockedView
&& dynamic_cast(new_focus)
&& !dynamic_cast(new_focus)->hasAncestor(mLockedView))))
@@ -291,7 +291,7 @@ void LLFocusMgr::setKeyboardFocus(LLFocusableElement* new_focus, BOOL lock, BOOL
// If we've got a default keyboard focus, and the caller is
// releasing keyboard focus, move to the default.
- if (mDefaultKeyboardFocus != NULL && mKeyboardFocus == NULL)
+ if (mDefaultKeyboardFocus != nullptr && mKeyboardFocus == nullptr)
{
mDefaultKeyboardFocus->setFocus(TRUE);
}
@@ -343,7 +343,7 @@ BOOL LLFocusMgr::childHasKeyboardFocus(const LLView* parent ) const
// Returns TRUE is parent or any descedent of parent is the mouse captor.
BOOL LLFocusMgr::childHasMouseCapture( const LLView* parent ) const
{
- if( mMouseCaptor && dynamic_cast(mMouseCaptor) != NULL )
+ if( mMouseCaptor && dynamic_cast(mMouseCaptor) != nullptr )
{
LLView* captor_view = (LLView*)mMouseCaptor;
while( captor_view )
@@ -364,23 +364,24 @@ void LLFocusMgr::removeKeyboardFocusWithoutCallback( const LLFocusableElement* f
// in order to unlock it
if (focus == mLockedView)
{
- mLockedView = NULL;
+ mLockedView = nullptr;
}
+
if (mKeyboardFocus == focus)
{
- mKeyboardFocus = NULL;
+ mKeyboardFocus = nullptr;
}
if (mLastKeyboardFocus == focus)
{
- mLastKeyboardFocus = NULL;
+ mLastKeyboardFocus = nullptr;
}
if (mDefaultKeyboardFocus == focus)
{
- mDefaultKeyboardFocus = NULL;
+ mDefaultKeyboardFocus = nullptr;
}
if (mLastDefaultKeyboardFocus == focus)
{
- mLastDefaultKeyboardFocus = NULL;
+ mLastDefaultKeyboardFocus = nullptr;
}
}
@@ -430,7 +431,7 @@ void LLFocusMgr::removeMouseCaptureWithoutCallback( const LLMouseHandler* captor
{
if( mMouseCaptor == captor )
{
- mMouseCaptor = NULL;
+ mMouseCaptor = nullptr;
}
}
@@ -470,7 +471,7 @@ void LLFocusMgr::removeTopCtrlWithoutCallback( const LLUICtrl* top_view )
{
if( mTopCtrl == top_view )
{
- mTopCtrl = NULL;
+ mTopCtrl = nullptr;
}
}
@@ -481,7 +482,7 @@ void LLFocusMgr::lockFocus()
void LLFocusMgr::unlockFocus()
{
- mLockedView = NULL;
+ mLockedView = nullptr;
}
F32 LLFocusMgr::getFocusFlashAmt() const
@@ -516,7 +517,7 @@ void LLFocusMgr::setAppHasFocus(BOOL focus)
// release focus from "top ctrl"s, which generally hides them
if (!focus && mTopCtrl)
{
- setTopCtrl(NULL);
+ setTopCtrl(nullptr);
}
mAppHasFocus = focus;
}
@@ -532,7 +533,7 @@ LLUICtrl* LLFocusMgr::getLastFocusForGroup(LLView* subtree_root) const
return static_cast(found_it->second.get());
}
}
- return NULL;
+ return nullptr;
}
void LLFocusMgr::clearLastFocusForGroup(LLView* subtree_root)
diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp
index 66b8d64ec..1db2638e0 100644
--- a/indra/llui/lllineeditor.cpp
+++ b/indra/llui/lllineeditor.cpp
@@ -1497,8 +1497,9 @@ BOOL LLLineEditor::handleSpecialKey(KEY key, MASK mask)
break;
case KEY_RETURN:
+ if (getCommitOnReturn()) onCommit();
// store sent line in history
- updateHistory();
+ else updateHistory();
break;
case KEY_ESCAPE:
diff --git a/indra/llui/llloadingindicator.cpp b/indra/llui/llloadingindicator.cpp
new file mode 100644
index 000000000..915571874
--- /dev/null
+++ b/indra/llui/llloadingindicator.cpp
@@ -0,0 +1,104 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check it.
+// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+/**
+ * @file llloadingindicator.cpp
+ * @brief Perpetual loading indicator
+ *
+ * $LicenseInfo:firstyear=2010&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include "llloadingindicator.h"
+
+// Linden library includes
+#include "llsingleton.h"
+
+// Project includes
+#include "lluictrlfactory.h"
+#include "lluiimage.h"
+
+static LLRegisterWidget r("loading_indicator");
+
+///////////////////////////////////////////////////////////////////////////////
+// LLLoadingIndicator class
+///////////////////////////////////////////////////////////////////////////////
+
+LLLoadingIndicator::LLLoadingIndicator(const Params& p)
+: LLUICtrl(p),
+ mImagesPerSec(p.images_per_sec > 0 ? p.images_per_sec : 1.0f),
+ mCurImageIdx(0)
+{
+}
+
+void LLLoadingIndicator::initFromParams(const Params& p)
+{
+ for (LLUIImage* image : p.images().image)
+ {
+ mImages.push_back(image);
+ }
+
+ if (mImages.empty()) // Singu Note: We don't have default widgets yet, so let's just handle this here
+ for (int i = 1; i <= 12; ++i)
+ mImages.push_back(LLUI::getUIImage(llformat("Progress_%d", i)));
+
+ // Start timer for switching images.
+ start();
+}
+
+void LLLoadingIndicator::draw()
+{
+ // Time to switch to the next image?
+ if (mImageSwitchTimer.getStarted() && mImageSwitchTimer.hasExpired())
+ {
+ // Switch to the next image.
+ if (!mImages.empty())
+ {
+ mCurImageIdx = (mCurImageIdx + 1) % mImages.size();
+ }
+
+ // Restart timer.
+ start();
+ }
+
+ LLUIImagePtr cur_image = mImages.empty() ? LLUIImagePtr(NULL) : mImages[mCurImageIdx];
+
+ // Draw current image.
+ if( cur_image.notNull() )
+ {
+ cur_image->draw(getLocalRect(), LLColor4::white % getDrawContext().mAlpha);
+ }
+
+ LLUICtrl::draw();
+}
+
+void LLLoadingIndicator::stop()
+{
+ mImageSwitchTimer.stop();
+}
+
+void LLLoadingIndicator::start()
+{
+ mImageSwitchTimer.start();
+ F32 period = 1.0f / (mImages.size() * mImagesPerSec);
+ mImageSwitchTimer.setTimerExpirySec(period);
+}
diff --git a/indra/llui/llloadingindicator.h b/indra/llui/llloadingindicator.h
new file mode 100644
index 000000000..b5e86c0ac
--- /dev/null
+++ b/indra/llui/llloadingindicator.h
@@ -0,0 +1,104 @@
+/**
+ * @file llloadingindicator.h
+ * @brief Perpetual loading indicator
+ *
+ * $LicenseInfo:firstyear=2010&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLLOADINGINDICATOR_H
+#define LL_LLLOADINGINDICATOR_H
+
+#include "lluictrl.h"
+#include "lluiimage.h"
+
+///////////////////////////////////////////////////////////////////////////////
+// class LLLoadingIndicator
+///////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Perpetual loading indicator (a la MacOSX or YouTube)
+ *
+ * Number of rotations per second can be overridden
+ * with the "images_per_sec" parameter.
+ *
+ * Can start/stop spinning.
+ *
+ * @see start()
+ * @see stop()
+ */
+class LLLoadingIndicator
+: public LLUICtrl
+{
+ LOG_CLASS(LLLoadingIndicator);
+public:
+
+ struct Images : public LLInitParam::Block
+ {
+ Multiple image;
+
+ Images()
+ : image("image")
+ {}
+ };
+
+ struct Params : public LLInitParam::Block
+ {
+ Optional images_per_sec;
+ Optional > images;
+
+ Params()
+ : images_per_sec("images_per_sec", 1.0f),
+ images("images")
+ {}
+ };
+
+ virtual ~LLLoadingIndicator() {}
+
+ // llview overrides
+ void draw() override;
+
+ /**
+ * Stop spinning.
+ */
+ void stop();
+
+ /**
+ * Start spinning.
+ */
+ void start();
+
+ void reset() { mCurImageIdx = 0; }
+
+private:
+ LLLoadingIndicator(const Params&);
+ void initFromParams(const Params&);
+
+ friend class LLUICtrlFactory;
+
+ F32 mImagesPerSec;
+ S8 mCurImageIdx;
+ LLFrameTimer mImageSwitchTimer;
+
+ std::vector mImages;
+};
+
+#endif // LL_LLLOADINGINDICATOR_H
diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp
index 3dd787089..4b38899d3 100644
--- a/indra/llui/llmenugl.cpp
+++ b/indra/llui/llmenugl.cpp
@@ -70,7 +70,7 @@
using namespace LLOldEvents;
// static
-LLMenuHolderGL *LLMenuGL::sMenuContainer = NULL;
+LLMenuHolderGL *LLMenuGL::sMenuContainer = nullptr;
S32 MENU_BAR_HEIGHT = 0;
S32 MENU_BAR_WIDTH = 0;
@@ -258,7 +258,7 @@ BOOL LLMenuItemGL::handleRightMouseUp(S32 x, S32 y, MASK mask)
// if not, it will be added to the list
BOOL LLMenuItemGL::addToAcceleratorList(std::list *listp)
{
- LLKeyBinding *accelerator = NULL;
+ LLKeyBinding *accelerator = nullptr;
if (mAcceleratorKey != KEY_NONE)
{
@@ -268,19 +268,37 @@ BOOL LLMenuItemGL::addToAcceleratorList(std::list *listp)
accelerator = *list_it;
if ((accelerator->mKey == mAcceleratorKey) && (accelerator->mMask == (mAcceleratorMask & MASK_NORMALKEYS)))
{
+
+ // *NOTE: get calling code to throw up warning or route
+ // warning messages back to app-provided output
+ // std::string warning;
+ // warning.append("Duplicate key binding <");
+ // appendAcceleratorString( warning );
+ // warning.append("> for menu items:\n ");
+ // warning.append(accelerator->mName);
+ // warning.append("\n ");
+ // warning.append(mLabel);
+
+ // LL_WARNS() << warning << LL_ENDL;
+ // LLAlertDialog::modalAlert(warning);
return FALSE;
}
}
if (!accelerator)
{
- accelerator = new LLKeyBinding;
- if (accelerator)
+ try
{
+ accelerator = new LLKeyBinding;
accelerator->mKey = mAcceleratorKey;
accelerator->mMask = (mAcceleratorMask & MASK_NORMALKEYS);
// accelerator->mName = mLabel;
+ listp->push_back(accelerator);//addData(accelerator);
+ }
+ catch (const std::bad_alloc& e)
+ {
+ LL_WARNS() << "Failed to allocate memory for keybinding with exception: " << e.what() << LL_ENDL;
+ return FALSE;
}
- listp->push_back(accelerator);//addData(accelerator);
}
}
return TRUE;
@@ -681,7 +699,7 @@ class LLMenuItemVerticalSeparatorGL
public:
LLMenuItemVerticalSeparatorGL( void );
- virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask) { return FALSE; }
+ BOOL handleMouseDown(S32 x, S32 y, MASK mask) override { return FALSE; }
};
LLMenuItemVerticalSeparatorGL::LLMenuItemVerticalSeparatorGL( void )
@@ -733,7 +751,7 @@ LLFloater* LLMenuItemTearOffGL::getParentFloater()
}
}
- return NULL;
+ return nullptr;
}
void LLMenuItemTearOffGL::onCommit()
@@ -4873,7 +4891,7 @@ void LLContextMenu::hide()
{
mHoverItem->setHighlight( FALSE );
}
- mHoverItem = NULL;
+ mHoverItem = nullptr;
}
@@ -4983,7 +5001,11 @@ bool LLContextMenu::addChild(LLView* view, S32 tab_group)
if (LLContextMenu* context = dynamic_cast(view))
return appendContextSubMenu(context);
if (LLMenuItemGL* item = dynamic_cast(view))
+ {
+ if (!mItems.empty() && mItems.back()->getType() == "separator" && item->getType() == "separator") // Singu TODO: Profile this? Does it matter?
+ item->setVisible(false);
return append(item);
+ }
if (LLMenuGL* menu = dynamic_cast(view))
return appendMenu(menu);
return false;
@@ -5024,7 +5046,7 @@ LLPieMenu::LLPieMenu(const std::string& name, const std::string& label)
// Separators on pie menus are invisible
bool LLPieMenu::addChild(LLView* view, S32 tab_group)
{
- if (LLContextMenu::addChild(view, tab_group))
+ if (LLContextMenu::addChild(view, tab_group) && view->getVisible())
{
LLMenuItemSeparatorGL* sep = dynamic_cast(view);
if(sep)
diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h
index 4c5811321..7c3626d35 100644
--- a/indra/llui/llmenugl.h
+++ b/indra/llui/llmenugl.h
@@ -580,6 +580,7 @@ public:
void resetScrollPositionOnShow(bool reset_scroll_pos) { mResetScrollPositionOnShow = reset_scroll_pos; }
bool isScrollPositionOnShowReset() { return mResetScrollPositionOnShow; }
protected:
+ friend class LLTextEditor;
void createSpilloverBranch();
void cleanupSpilloverBranch();
// Add the menu item to this menu.
diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp
index 5c9dfb74a..1f2f4cec4 100644
--- a/indra/llui/llnotifications.cpp
+++ b/indra/llui/llnotifications.cpp
@@ -284,7 +284,8 @@ LLNotificationForm::LLNotificationForm(const LLSD& sd)
}
else
{
- LL_WARNS() << "Invalid form data " << sd << LL_ENDL;
+ if (!sd.isUndefined())
+ LL_WARNS() << "Invalid form data " << sd << LL_ENDL;
mFormData = LLSD::emptyArray();
}
}
diff --git a/indra/llui/llpanel.cpp b/indra/llui/llpanel.cpp
index b587de148..e311daa1c 100644
--- a/indra/llui/llpanel.cpp
+++ b/indra/llui/llpanel.cpp
@@ -196,14 +196,16 @@ void LLPanel::draw()
// draw background
if( mBgVisible )
{
- LLRect local_rect = getLocalRect();
+ F32 alpha = getCurrentTransparency();
+
+ LLRect&& local_rect = getLocalRect();
if (mBgOpaque )
{
- gl_rect_2d( local_rect, mBgColorOpaque );
+ gl_rect_2d( local_rect, mBgColorOpaque % alpha);
}
else
{
- gl_rect_2d( local_rect, mBgColorAlpha );
+ gl_rect_2d( local_rect, mBgColorAlpha % alpha);
}
}
@@ -439,8 +441,31 @@ LLView* LLPanel::fromXML(LLXMLNodePtr node, LLView* parent, LLUICtrlFactory *fac
std::string name("panel");
node->getAttributeString("name", name);
- LLPanel* panelp = factory->createFactoryPanel(name);
+ std::string class_attr;
+ node->getAttributeString("class", class_attr);
+
+ LLPanel* panelp = NULL;
+
+ {
+ if(!class_attr.empty())
+ {
+ panelp = LLRegisterPanelClass::instance().createPanelClass(class_attr);
+ }
+
+ if (!panelp)
+ {
+ panelp = factory->createFactoryPanel(name);
+ /* Singu TODO: Future?
+ llassert(panelp);
+
+ if (!panelp)
+ {
+ return NULL; // :(
+ }*/
+ }
+ }
LL_RECORD_BLOCK_TIME(FTM_PANEL_CONSTRUCTION);
+
// Fall back on a default panel, if there was no special factory.
if (!panelp)
{
diff --git a/indra/llui/llpanel.h b/indra/llui/llpanel.h
index d2ca151e5..f379cd2a6 100644
--- a/indra/llui/llpanel.h
+++ b/indra/llui/llpanel.h
@@ -39,8 +39,8 @@
#include "lluictrl.h"
#include "llbutton.h"
#include "lllineeditor.h"
-#include "lluiimage.h"
#include "llviewborder.h"
+#include "lluiimage.h"
#include "lluistring.h"
#include "v4color.h"
#include
@@ -142,6 +142,7 @@ public:
CommitCallbackRegistry::ScopedRegistrar& getCommitCallbackRegistrar() { return mCommitCallbackRegistrar; }
EnableCallbackRegistry::ScopedRegistrar& getEnableCallbackRegistrar() { return mEnableCallbackRegistrar; }
+
virtual BOOL initPanelXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
void initChildrenXML(LLXMLNodePtr node, LLUICtrlFactory* factory);
void setPanelParameters(LLXMLNodePtr node, LLView *parentp);
@@ -151,6 +152,7 @@ public:
std::string getString(const std::string& name) const;
// ** Wrappers for setting child properties by name ** -TomY
+ // WARNING: These are deprecated, please use getChild("name")->doStuff() idiom instead
// LLView
void childSetVisible(const std::string& name, bool visible);
@@ -196,7 +198,7 @@ public:
BOOL childSetTextArg(const std::string& id, const std::string& key, const LLStringExplicit& text);
BOOL childSetLabelArg(const std::string& id, const std::string& key, const LLStringExplicit& text);
BOOL childSetToolTipArg(const std::string& id, const std::string& key, const LLStringExplicit& text);
-
+
// LLSlider / LLMultiSlider / LLSpinCtrl
void childSetMinValue(const std::string& id, LLSD min_value);
void childSetMaxValue(const std::string& id, LLSD max_value);
@@ -228,6 +230,7 @@ public:
static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
boost::signals2::connection setVisibleCallback( const commit_signal_t::slot_type& cb );
+
protected:
// Override to set not found list
LLButton* getDefaultButton() { return mDefaultBtn; }
@@ -262,4 +265,56 @@ private:
}; // end class LLPanel
+typedef boost::function LLPanelClassCreatorFunc;
+
+// local static instance for registering a particular panel class
+
+class LLRegisterPanelClass
+: public LLSingleton< LLRegisterPanelClass >
+{
+public:
+ // reigister with either the provided builder, or the generic templated builder
+ void addPanelClass(const std::string& tag,LLPanelClassCreatorFunc func)
+ {
+ mPanelClassesNames[tag] = func;
+ }
+
+ LLPanel* createPanelClass(const std::string& tag)
+ {
+ param_name_map_t::iterator iT = mPanelClassesNames.find(tag);
+ if(iT == mPanelClassesNames.end())
+ return 0;
+ return iT->second();
+ }
+ template
+ static T* defaultPanelClassBuilder()
+ {
+ T* pT = new T();
+ return pT;
+ }
+
+private:
+ typedef std::map< std::string, LLPanelClassCreatorFunc> param_name_map_t;
+
+ param_name_map_t mPanelClassesNames;
+};
+
+
+// local static instance for registering a particular panel class
+template
+ class LLPanelInjector
+{
+public:
+ // register with either the provided builder, or the generic templated builder
+ LLPanelInjector(const std::string& tag);
+};
+
+
+template
+ LLPanelInjector::LLPanelInjector(const std::string& tag)
+{
+ LLRegisterPanelClass::instance().addPanelClass(tag,&LLRegisterPanelClass::defaultPanelClassBuilder);
+}
+
+
#endif
diff --git a/indra/llui/llslider.cpp b/indra/llui/llslider.cpp
index 8e7e886ef..10beb2477 100644
--- a/indra/llui/llslider.cpp
+++ b/indra/llui/llslider.cpp
@@ -54,7 +54,6 @@ LLSlider::LLSlider(
F32 min_value,
F32 max_value,
F32 increment,
- BOOL volume,
const std::string& control_name)
:
LLUICtrl( name, rect, TRUE, commit_callback,
@@ -64,7 +63,6 @@ LLSlider::LLSlider(
mMinValue( min_value ),
mMaxValue( max_value ),
mIncrement( increment ),
- mVolumeSlider( volume ),
mMouseOffset( 0 ),
mTrackColor( LLUI::sColorsGroup->getColor( "SliderTrackColor" ) ),
mThumbOutlineColor( LLUI::sColorsGroup->getColor( "SliderThumbOutlineColor" ) ),
@@ -172,7 +170,7 @@ BOOL LLSlider::handleMouseUp(S32 x, S32 y, MASK mask)
if( hasMouseCapture() )
{
- gFocusMgr.setMouseCapture( NULL );
+ gFocusMgr.setMouseCapture(nullptr );
if (mMouseUpSignal)
(*mMouseUpSignal)( this, getValueF32() );
@@ -229,15 +227,12 @@ BOOL LLSlider::handleKeyHere(KEY key, MASK mask)
BOOL handled = FALSE;
switch(key)
{
- case KEY_UP:
case KEY_DOWN:
- // eat up and down keys to be consistent
- handled = TRUE;
- break;
case KEY_LEFT:
setValueAndCommit(getValueF32() - getIncrement());
handled = TRUE;
break;
+ case KEY_UP:
case KEY_RIGHT:
setValueAndCommit(getValueF32() + getIncrement());
handled = TRUE;
@@ -248,6 +243,16 @@ BOOL LLSlider::handleKeyHere(KEY key, MASK mask)
return handled;
}
+BOOL LLSlider::handleScrollWheel(S32 x, S32 y, S32 clicks)
+{
+ F32 old_val = getValueF32();
+ F32 new_val = old_val - clicks * getIncrement();
+ setValueAndCommit(new_val);
+ // Singu Note: We have to tell the viewer we're done dragging if it cares
+ if (mMouseUpSignal && old_val != new_val) (*mMouseUpSignal)(this, new_val);
+ return TRUE;
+}
+
void LLSlider::draw()
{
F32 alpha = getDrawContext().mAlpha;
@@ -276,7 +281,7 @@ void LLSlider::draw()
mThumbImage->drawBorder(mThumbRect, gFocusMgr.getFocusColor() % alpha, gFocusMgr.getFocusFlashWidth());
}
- if( hasMouseCapture() )
+ if( hasMouseCapture() ) // currently clicking on slider
{
// Show ghost where thumb was before dragging began.
if (mThumbImage.notNull())
@@ -310,20 +315,11 @@ LLXMLNodePtr LLSlider::getXML(bool save_children) const
{
LLXMLNodePtr node = LLUICtrl::getXML();
- if (mVolumeSlider)
- {
- node->setName(LL_VOLUME_SLIDER_CTRL_TAG);
- }
- else
- {
- node->setName(LL_SLIDER_TAG);
- }
-
+ node->setName(LL_SLIDER_TAG);
node->createChild("initial_val", TRUE)->setFloatValue(getInitialValue());
node->createChild("min_val", TRUE)->setFloatValue(getMinValue());
node->createChild("max_val", TRUE)->setFloatValue(getMaxValue());
node->createChild("increment", TRUE)->setFloatValue(getIncrement());
- node->createChild("volume", TRUE)->setBoolValue(mVolumeSlider);
return node;
}
@@ -358,17 +354,13 @@ LLView* LLSlider::fromXML(LLXMLNodePtr node, LLView *parent, class LLUICtrlFacto
F32 increment = 0.1f;
node->getAttributeF32("increment", increment);
- BOOL volume = node->hasName("volume_slider") ? TRUE : FALSE;
- node->getAttributeBOOL("volume", volume);
-
LLSlider* slider = new LLSlider("slider_bar",
rect,
NULL,
initial_value,
min_value,
max_value,
- increment,
- volume);
+ increment);
slider->initFromXML(node, parent);
diff --git a/indra/llui/llslider.h b/indra/llui/llslider.h
index 59bda673f..4fe90193e 100644
--- a/indra/llui/llslider.h
+++ b/indra/llui/llslider.h
@@ -48,7 +48,6 @@ public:
F32 min_value,
F32 max_value,
F32 increment,
- BOOL volume, //TODO: create a "volume" slider sub-class or just use image art, no? -MG
const std::string& control_name = LLStringUtil::null );
virtual LLXMLNodePtr getXML(bool save_children = true) const;
@@ -75,12 +74,12 @@ public:
boost::signals2::connection setMouseDownCallback( const commit_signal_t::slot_type& cb );
boost::signals2::connection setMouseUpCallback( const commit_signal_t::slot_type& cb );
-
- virtual BOOL handleHover(S32 x, S32 y, MASK mask);
- virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask);
- virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
- virtual BOOL handleKeyHere(KEY key, MASK mask);
- virtual void draw();
+ BOOL handleHover(S32 x, S32 y, MASK mask) override;
+ BOOL handleMouseUp(S32 x, S32 y, MASK mask) override;
+ BOOL handleMouseDown(S32 x, S32 y, MASK mask) override;
+ BOOL handleKeyHere(KEY key, MASK mask) override;
+ BOOL handleScrollWheel(S32 x, S32 y, S32 clicks) override;
+ void draw() override;
private:
void setValueAndCommit(F32 value);
@@ -92,7 +91,6 @@ private:
F32 mMaxValue;
F32 mIncrement;
- BOOL mVolumeSlider;
S32 mMouseOffset;
LLRect mDragStartThumbRect;
diff --git a/indra/llui/llsliderctrl.cpp b/indra/llui/llsliderctrl.cpp
index be2562e6d..0f164711e 100644
--- a/indra/llui/llsliderctrl.cpp
+++ b/indra/llui/llsliderctrl.cpp
@@ -59,7 +59,6 @@ LLSliderCtrl::LLSliderCtrl(const std::string& name, const LLRect& rect,
S32 text_left,
BOOL show_text,
BOOL can_edit_text,
- BOOL volume,
commit_callback_t commit_callback,
F32 initial_value, F32 min_value, F32 max_value, F32 increment,
const std::string& control_which)
@@ -67,7 +66,6 @@ LLSliderCtrl::LLSliderCtrl(const std::string& name, const LLRect& rect,
mFont(font),
mShowText( show_text ),
mCanEditText( can_edit_text ),
- mVolumeSlider( volume ),
mPrecision( 3 ),
mLabelBox( NULL ),
mLabelWidth( label_width ),
@@ -105,7 +103,7 @@ LLSliderCtrl::LLSliderCtrl(const std::string& name, const LLRect& rect,
mSlider = new LLSlider(std::string("slider"),
slider_rect,
boost::bind(&LLSliderCtrl::onSliderCommit,_1,_2),
- initial_value, min_value, max_value, increment, volume,
+ initial_value, min_value, max_value, increment,
control_which );
addChild( mSlider );
@@ -387,8 +385,6 @@ LLXMLNodePtr LLSliderCtrl::getXML(bool save_children) const
node->createChild("show_text", TRUE)->setBoolValue(mShowText);
node->createChild("can_edit_text", TRUE)->setBoolValue(mCanEditText);
-
- node->createChild("volume", TRUE)->setBoolValue(mVolumeSlider);
node->createChild("decimal_digits", TRUE)->setIntValue(mPrecision);
@@ -438,9 +434,6 @@ LLView* LLSliderCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory
BOOL can_edit_text = FALSE;
node->getAttributeBOOL("can_edit_text", can_edit_text);
- BOOL volume = FALSE;
- node->getAttributeBOOL("volume", volume);
-
F32 initial_value = 0.f;
node->getAttributeF32("initial_val", initial_value);
@@ -497,7 +490,6 @@ LLView* LLSliderCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory
rect.getWidth() - text_left,
show_text,
can_edit_text,
- volume,
NULL,
initial_value,
min_value,
diff --git a/indra/llui/llsliderctrl.h b/indra/llui/llsliderctrl.h
index a5bc3488c..0b173a531 100644
--- a/indra/llui/llsliderctrl.h
+++ b/indra/llui/llsliderctrl.h
@@ -57,7 +57,6 @@ public:
S32 text_left,
BOOL show_text,
BOOL can_edit_text,
- BOOL volume, //TODO: create a "volume" slider sub-class or just use image art, no? -MG
commit_callback_t commit_callback,
F32 initial_value, F32 min_value, F32 max_value, F32 increment,
const std::string& control_which = LLStringUtil::null );
@@ -125,8 +124,7 @@ private:
const LLFontGL* mFont;
BOOL mShowText;
BOOL mCanEditText;
- BOOL mVolumeSlider;
-
+
S32 mPrecision;
LLTextBox* mLabelBox;
S32 mLabelWidth;
diff --git a/indra/llui/llstatbar.cpp b/indra/llui/llstatbar.cpp
index 751156a31..dca6e79d0 100644
--- a/indra/llui/llstatbar.cpp
+++ b/indra/llui/llstatbar.cpp
@@ -175,17 +175,15 @@ void LLStatBar::draw()
LLFontGL::getFontMonospace()->renderUTF8(mLabel, 0, 0, getRect().getHeight(), LLColor4(1.f, 1.f, 1.f, 1.f),
LLFontGL::LEFT, LLFontGL::TOP);
- std::string value_format;
+
std::string value_str;
if (!mUnitLabel.empty())
{
- value_format = llformat( "%%.%df%%s", mPrecision);
- value_str = llformat( value_format.c_str(), mValue, mUnitLabel.c_str());
+ value_str = llformat( "%.*f%s", mPrecision, mValue, mUnitLabel.c_str());
}
else
{
- value_format = llformat( "%%.%df", mPrecision);
- value_str = llformat( value_format.c_str(), mValue);
+ value_str = llformat("%.*f", mPrecision, mValue);
}
// Draw the value.
@@ -193,11 +191,8 @@ void LLStatBar::draw()
LLColor4(1.f, 1.f, 1.f, 0.5f),
LLFontGL::RIGHT, LLFontGL::TOP);
- value_format = llformat( "%%.%df", mPrecision);
if (mDisplayBar)
{
- std::string tick_label;
-
// Draw the tick marks.
F32 tick_value;
top = bar_top;
@@ -220,9 +215,8 @@ void LLStatBar::draw()
right = left + tick_width;
gl_rect_2d(left, top, right, bottom, LLColor4(1.f, 1.f, 1.f, 0.25f));
- tick_label = llformat( value_format.c_str(), tick_value);
// draw labels for the tick marks
- LLFontGL::getFontMonospace()->renderUTF8(tick_label, 0, left - 1, bar_top - bar_height - tick_height,
+ LLFontGL::getFontMonospace()->renderUTF8(llformat("%.*f", mPrecision, tick_value), 0, left - 1, bar_top - bar_height - tick_height,
LLColor4(1.f, 1.f, 1.f, 0.5f),
LLFontGL::LEFT, LLFontGL::TOP);
}
diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp
index 1db493c01..3996470be 100644
--- a/indra/llui/lltexteditor.cpp
+++ b/indra/llui/lltexteditor.cpp
@@ -43,6 +43,7 @@
#include "lluictrlfactory.h"
#include "lluiimage.h"
#include "llurlaction.h"
+#include "llurlregistry.h"
#include "llrect.h"
#include "llfocusmgr.h"
#include "lltimer.h"
@@ -64,6 +65,7 @@
#include "lltextparser.h"
#include "lldir.h"
#include
+#include "llmemberlistener.h"
#include "llmenugl.h"
#include "../newview/lgghunspell_wrapper.h"
@@ -95,9 +97,6 @@ const S32 PREEDIT_STANDOUT_GAP = 1;
const S32 PREEDIT_STANDOUT_POSITION = 2;
const S32 PREEDIT_STANDOUT_THICKNESS = 2;
-
-LLColor4 LLTextEditor::mLinkColor = LLColor4::blue;
-
///////////////////////////////////////////////////////////////////
class LLTextEditor::LLTextCmdInsert : public LLTextEditor::LLTextCmd
@@ -245,47 +244,51 @@ private:
///////////////////////////////////////////////////////////////////
+LLTextEditor::is_friend_signal_t* LLTextEditor::mIsFriendSignal = nullptr;
+LLTextEditor::is_blocked_signal_t* LLTextEditor::mIsObjectBlockedSignal = nullptr;
-LLTextEditor::LLTextEditor(
- const std::string& name,
- const LLRect& rect,
+LLTextEditor::LLTextEditor(
+ const std::string& name,
+ const LLRect& rect,
S32 max_length, // In bytes
- const std::string &default_text,
+ const std::string &default_text,
const LLFontGL* font,
- BOOL allow_embedded_items)
- :
- LLUICtrl( name, rect, TRUE, NULL, FOLLOWS_TOP | FOLLOWS_LEFT ),
+ BOOL allow_embedded_items,
+ bool parse_html)
+ :
+ LLUICtrl(name, rect, TRUE, NULL, FOLLOWS_TOP | FOLLOWS_LEFT),
mTextIsUpToDate(TRUE),
- mMaxTextByteLength( max_length ),
+ mMaxTextByteLength(max_length),
mPopupMenuHandle(),
mBaseDocIsPristine(TRUE),
- mPristineCmd( NULL ),
- mLastCmd( NULL ),
- mCursorPos( 0 ),
- mIsSelecting( FALSE ),
- mSelectionStart( 0 ),
- mSelectionEnd( 0 ),
- mScrolledToBottom( TRUE ),
- mOnScrollEndCallback( NULL ),
- mOnScrollEndData( NULL ),
- mCursorColor( LLUI::sColorsGroup->getColor( "TextCursorColor" ) ),
- mFgColor( LLUI::sColorsGroup->getColor( "TextFgColor" ) ),
- mDefaultColor( LLUI::sColorsGroup->getColor( "TextDefaultColor" ) ),
- mReadOnlyFgColor( LLUI::sColorsGroup->getColor( "TextFgReadOnlyColor" ) ),
- mWriteableBgColor( LLUI::sColorsGroup->getColor( "TextBgWriteableColor" ) ),
- mReadOnlyBgColor( LLUI::sColorsGroup->getColor( "TextBgReadOnlyColor" ) ),
- mFocusBgColor( LLUI::sColorsGroup->getColor( "TextBgFocusColor" ) ),
- mReadOnly(FALSE),
- mWordWrap( FALSE ),
- mShowLineNumbers ( FALSE ),
- mTabsToNextField( TRUE ),
- mCommitOnFocusLost( FALSE ),
- mHideScrollbarForShortDocs( FALSE ),
- mTakesNonScrollClicks( TRUE ),
- mTrackBottom( FALSE ),
- mAllowEmbeddedItems( allow_embedded_items ),
+ mPristineCmd(NULL),
+ mLastCmd(NULL),
+ mCursorPos(0),
+ mIsSelecting(FALSE),
+ mSelectionStart(0),
+ mSelectionEnd(0),
+ mScrolledToBottom(TRUE),
+ mOnScrollEndCallback(NULL),
+ mOnScrollEndData(NULL),
+ mCursorColor(LLUI::sColorsGroup->getColor("TextCursorColor")),
+ mFgColor(LLUI::sColorsGroup->getColor("TextFgColor")),
+ mDefaultColor(LLUI::sColorsGroup->getColor("TextDefaultColor")),
+ mReadOnlyFgColor(LLUI::sColorsGroup->getColor("TextFgReadOnlyColor")),
+ mWriteableBgColor(LLUI::sColorsGroup->getColor("TextBgWriteableColor")),
+ mReadOnlyBgColor(LLUI::sColorsGroup->getColor("TextBgReadOnlyColor")),
+ mFocusBgColor(LLUI::sColorsGroup->getColor("TextBgFocusColor")),
+ mLinkColor(nullptr),
+ mReadOnly(parse_html),
+ mWordWrap(FALSE),
+ mShowLineNumbers(FALSE),
+ mTabsToNextField(TRUE),
+ mCommitOnFocusLost(FALSE),
+ mHideScrollbarForShortDocs(FALSE),
+ mTakesNonScrollClicks(TRUE),
+ mTrackBottom(FALSE),
+ mAllowEmbeddedItems(allow_embedded_items),
mAcceptCallingCardNames(FALSE),
- mHandleEditKeysDirectly( FALSE ),
+ mHandleEditKeysDirectly(FALSE),
mMouseDownX(0),
mMouseDownY(0),
mLastSelectionX(-1),
@@ -312,56 +315,39 @@ LLTextEditor::LLTextEditor(
updateTextRect();
- S32 line_height = ll_round( mGLFont->getLineHeight() );
+ S32 line_height = ll_round(mGLFont->getLineHeight());
S32 page_size = mTextRect.getHeight() / line_height;
// Init the scrollbar
LLRect scroll_rect;
- scroll_rect.setOriginAndSize(
+ scroll_rect.setOriginAndSize(
getRect().getWidth() - SCROLLBAR_SIZE,
1,
SCROLLBAR_SIZE,
getRect().getHeight() - 1);
S32 lines_in_doc = getLineCount();
- mScrollbar = new LLScrollbar( std::string("Scrollbar"), scroll_rect,
+ mScrollbar = new LLScrollbar(std::string("Scrollbar"), scroll_rect,
LLScrollbar::VERTICAL,
- lines_in_doc,
- 0,
+ lines_in_doc,
+ 0,
page_size,
NULL);
mScrollbar->setFollowsRight();
mScrollbar->setFollowsTop();
mScrollbar->setFollowsBottom();
- mScrollbar->setEnabled( TRUE );
- mScrollbar->setVisible( TRUE );
+ mScrollbar->setEnabled(TRUE);
+ mScrollbar->setVisible(TRUE);
mScrollbar->setOnScrollEndCallback(mOnScrollEndCallback, mOnScrollEndData);
addChild(mScrollbar);
- mBorder = new LLViewBorder( std::string("text ed border"), LLRect(0, getRect().getHeight(), getRect().getWidth(), 0), LLViewBorder::BEVEL_IN, LLViewBorder::STYLE_LINE, UI_TEXTEDITOR_BORDER );
- addChild( mBorder );
+ mBorder = new LLViewBorder(std::string("text ed border"), LLRect(0, getRect().getHeight(), getRect().getWidth(), 0), LLViewBorder::BEVEL_IN, LLViewBorder::STYLE_LINE, UI_TEXTEDITOR_BORDER);
+ addChild(mBorder);
+ mParseHTML = parse_html;
appendText(default_text, FALSE, FALSE);
-
+
resetDirty(); // Update saved text state
- mParseHTML=FALSE;
- mHTML.clear();
- // make the popup menu available
- //LLMenuGL* menu = LLUICtrlFactory::getInstance()->buildMenu("menu_texteditor.xml", parent_view);
- LLMenuGL* menu = new LLMenuGL("rclickmenu");
- /*if (!menu)
- {
- menu = new LLMenuGL(LLStringUtil::null);
- }*/
- menu->addChild(new LLMenuItemCallGL("Cut", context_cut, NULL, this));
- menu->addChild(new LLMenuItemCallGL("Copy", context_copy, NULL, this));
- menu->addChild(new LLMenuItemCallGL("Paste", context_paste, NULL, this));
- menu->addChild(new LLMenuItemCallGL("Delete", context_delete, NULL, this));
- menu->addChild(new LLMenuItemCallGL("Select All", context_selectall, NULL, this));
- menu->addSeparator();
- menu->setCanTearOff(FALSE);
- menu->setVisible(FALSE);
- mPopupMenuHandle = menu->getHandle();
setCommitCallback(boost::bind(&LLTextEditor::setControlValue, this, _2));
}
@@ -369,23 +355,100 @@ LLTextEditor::LLTextEditor(
LLTextEditor::~LLTextEditor()
{
gFocusMgr.releaseFocusIfNeeded( this ); // calls onCommit()
+ if (mLinkColor)
+ {
+ delete mLinkColor;
+ mLinkColor = nullptr;
+ }
// Scrollbar is deleted by LLView
std::for_each(mUndoStack.begin(), mUndoStack.end(), DeletePointer());
- //LLView::deleteViewByHandle(mPopupMenuHandle);
+ mSegments.clear();
+ auto menu = mPopupMenuHandle.get();
+ if (menu)
+ {
+ menu->die();
+ mPopupMenuHandle.markDead();
+ }
+ /* Singu Note: Static this, we'll use it wherever we can!
+ delete mIsFriendSignal;
+ delete mIsObjectBlockedSignal;*/
}
-void LLTextEditor::context_cut(void* data)
+
+const std::string& LLTextEditor::getMenuSegmentUrl() const
{
- LLTextEditor* line = (LLTextEditor*)data;
- if(line)line->cut();
+ auto segment = getSegmentAtLocalPos(mLastContextMenuX, mLastContextMenuY);
+ auto style = segment->getStyle();
+ return style ? style->getLinkHREF() : LLStringUtil::null;
}
-void LLTextEditor::context_copy(void* data)
+
+static LLTextEditor* get_focused_text_editor()
{
- LLTextEditor* line = (LLTextEditor*)data;
- if(line)line->copy();
+ auto* list = dynamic_cast(gFocusMgr.getKeyboardFocus());
+ llassert(list); // This listener only applies to lists
+ return list;
}
+class ContextText : public LLMemberListener
+{
+ bool handleEvent(LLPointer, const LLSD& userdata) override
+ {
+ auto text = get_focused_text_editor();
+ const auto& op = userdata.asStringRef();
+ if (op == "Cut") text->cut();
+ else if (op == "Copy") text->copy();
+ else if (op == "CopyRaw") text->copyRaw();
+ else if (op == "Paste") text->paste();
+ else if (op == "Delete") text->doDelete();
+ else if (op == "SelectAll") text->selectAll();
+ return true;
+ }
+};
+
+static const std::string& get_focused_url()
+{
+ return get_focused_text_editor()->getMenuSegmentUrl();
+}
+
+class ContextUrl : public LLMemberListener
+{
+ bool handleEvent(LLPointer, const LLSD& userdata) override
+ {
+ const auto& url = get_focused_url();
+ const auto& op = userdata.asStringRef();
+ if (op == "Open") LLUrlAction::openURL(url);
+ else if (op == "OpenInternal") LLUrlAction::openURLInternal(url);
+ else if (op == "OpenExternal") LLUrlAction::openURLExternal(url);
+ else if (op == "Execute") LLUrlAction::executeSLURL(url, true);
+ else if (op == "Block") LLUrlAction::blockObject(url);
+ else if (op == "Unblock") LLUrlAction::unblockObject(url);
+ else if (op == "Teleport") LLUrlAction::teleportToLocation(url);
+ else if (op == "ShowProfile") LLUrlAction::showProfile(url);
+ else if (op == "AddFriend") LLUrlAction::addFriend(url);
+ else if (op == "RemoveFriend") LLUrlAction::removeFriend(url);
+ else if (op == "SendIM") LLUrlAction::sendIM(url);
+ else if (op == "ShowOnMap") LLUrlAction::showLocationOnMap(url);
+ else if (op == "CopyLabel") LLUrlAction::copyLabelToClipboard(url);
+ else if (op == "CopyUrl") LLUrlAction::copyURLToClipboard(url);
+ return true;
+ }
+};
+
+class ContextUrlCopy : public LLMemberListener
+{
+
+ bool handleEvent(LLPointer, const LLSD& userdata) override
+ {
+ 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 true;
+ }
+};
+
void LLTextEditor::spell_correct(void* data)
{
@@ -463,21 +526,12 @@ void LLTextEditor::spell_add(void* data)
}
}
-
-void LLTextEditor::context_paste(void* data)
+//static
+void LLTextEditor::addMenuListeners()
{
- LLTextEditor* line = (LLTextEditor*)data;
- if(line)line->paste();
-}
-void LLTextEditor::context_delete(void* data)
-{
- LLTextEditor* line = (LLTextEditor*)data;
- if(line)line->doDelete();
-}
-void LLTextEditor::context_selectall(void* data)
-{
- LLTextEditor* line = (LLTextEditor*)data;
- if(line)line->selectAll();
+ (new ContextText)->registerListener(LLMenuGL::sMenuContainer, "Text");
+ (new ContextUrl)->registerListener(LLMenuGL::sMenuContainer, "Text.Url");
+ (new ContextUrlCopy)->registerListener(LLMenuGL::sMenuContainer, "Text.Url.CopyUUID");
}
void LLTextEditor::setTrackColor( const LLColor4& color )
@@ -637,40 +691,84 @@ BOOL LLTextEditor::truncate()
return did_truncate;
}
-void LLTextEditor::setText(const LLStringExplicit &utf8str)
+LLMenuGL* LLTextEditor::createUrlContextMenu(S32 x, S32 y, const std::string &in_url)
{
- // LLStringUtil::removeCRLF(utf8str);
- mUTF8Text = utf8str_removeCRLF(utf8str);
- // mUTF8Text = utf8str;
- mWText = utf8str_to_wstring(mUTF8Text);
- mTextIsUpToDate = TRUE;
+ // work out the XUI menu file to use for this url
+ LLUrlMatch match;
+ std::string url = in_url;
+ if (!LLUrlRegistry::instance().findUrl(url, match))
+ {
+ return nullptr;
+ }
- truncate();
- blockUndo();
+ std::string xui_file = match.getMenuName();
+ if (xui_file.empty())
+ {
+ return nullptr;
+ }
- setCursorPos(0);
- deselect();
+ // create and return the context menu from the XUI file
+ llassert(LLMenuGL::sMenuContainer != NULL);
+ auto menu = LLUICtrlFactory::getInstance()->buildMenu(xui_file, LLMenuGL::sMenuContainer);
+ if (menu)
+ {
+ if (mIsFriendSignal)
+ {
+ bool isFriend = *(*mIsFriendSignal)(LLUUID(LLUrlAction::getUserID(url)));
+ LLView* addFriendButton = menu->findChild("add_friend");
+ LLView* removeFriendButton = menu->findChild("remove_friend");
- needsReflow();
+ if (addFriendButton && removeFriendButton)
+ {
+ addFriendButton->setEnabled(!isFriend);
+ removeFriendButton->setEnabled(isFriend);
+ }
+ }
- resetDirty();
+ if (mIsObjectBlockedSignal)
+ {
+ bool is_blocked = *(*mIsObjectBlockedSignal)(LLUUID(LLUrlAction::getObjectId(url)), LLUrlAction::getObjectName(url));
+ LLView* blockButton = menu->findChild("block_object");
+ LLView* unblockButton = menu->findChild("unblock_object");
+
+ if (blockButton && unblockButton)
+ {
+ blockButton->setVisible(!is_blocked);
+ unblockButton->setVisible(is_blocked);
+ }
+ }
+ }
+ return menu;
}
-void LLTextEditor::setWText(const LLWString &wtext)
+void LLTextEditor::setText(const LLStringExplicit &utf8str)
{
- mWText = wtext;
- mUTF8Text.clear();
- mTextIsUpToDate = FALSE;
+ // clear out the existing text and segments
+ mWText.clear();
- truncate();
- blockUndo();
+ clearSegments();
+// createDefaultSegment();
- setCursorPos(0);
deselect();
- needsReflow();
+ // append the new text (supports Url linking)
+ std::string text(utf8str);
+ //LLStringUtil::removeCRLF(text);
+
+ // appendText modifies mCursorPos...
+ appendText(utf8str, false, false);
+ // ...so move cursor to top after appending text
+ setCursorPos(0);
resetDirty();
+
+ mUTF8Text = text;
+ mTextIsUpToDate = true;
+}
+
+void LLTextEditor::setWText(const LLWString& text)
+{
+ setText(wstring_to_utf8str(text));
}
// virtual
@@ -766,7 +864,7 @@ void LLTextEditor::selectNext(const std::string& search_text_in, BOOL case_insen
}
// If still -1, then search_text just isn't found.
- if (-1 == loc)
+ if (-1 == loc)
{
mIsSelecting = FALSE;
mSelectionEnd = 0;
@@ -889,9 +987,9 @@ S32 LLTextEditor::getLineStart( S32 line ) const
{
S32 num_lines = getLineCount();
if (num_lines == 0)
- {
+ {
return 0;
- }
+ }
line = llclamp(line, 0, num_lines-1);
S32 segidx = mLineStartList[line].mSegment;
@@ -1374,6 +1472,7 @@ BOOL LLTextEditor::handleMouseDown(S32 x, S32 y, MASK mask)
}
BOOL LLTextEditor::handleRightMouseDown( S32 x, S32 y, MASK mask )
{
+
setFocus(TRUE);
//setCursorAtLocalPos( x, y, TRUE );
@@ -1384,43 +1483,56 @@ BOOL LLTextEditor::handleRightMouseDown( S32 x, S32 y, MASK mask )
LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get();
if (menu)
{
- for(int i = 0;i<(int)suggestionMenuItems.size();i++)
+ for (auto tempBind : suggestionMenuItems)
{
- SpellMenuBind * tempBind = suggestionMenuItems[i];
- if(tempBind)
+ if (tempBind)
{
menu->removeChild(tempBind->menuItem);
tempBind->menuItem->die();
- //delete tempBind->menuItem;
- //tempBind->menuItem = NULL;
delete tempBind;
}
}
suggestionMenuItems.clear();
+ menu->die();
+ }
+
+ auto segment = getSegmentAtLocalPos(x, y);
+ const LLStyleSP style = segment ? segment->getStyle() : nullptr;
+ auto submenu = (style && style->isLink()) ? createUrlContextMenu(x, y, style->getLinkHREF()) : nullptr;
+ // Add url menu to base menu if we have a selection, otherwise make it the menu.
+ menu = (submenu && !hasSelection()) ? submenu : LLUICtrlFactory::getInstance()->buildMenu("menu_texteditor.xml", LLMenuGL::sMenuContainer);
+ mPopupMenuHandle = menu->getHandle();
+ if (menu)
+ {
+ if (submenu && submenu != menu)
+ {
+ submenu->removeChild(submenu->getChild("Select All")); // There can be only one!
+ menu->appendMenu(submenu);
+ }
// spell_check="true" in xui
- menu->setItemVisible("Spelsep", !mReadOnly && mSpellCheckable);
if (!mReadOnly && mSpellCheckable)
{
bool is_word_part = getWordBoundriesAt(pos, &wordStart, &wordLen);
if (is_word_part)
{
const LLWString &text = mWText;
- std::string selectedWord(std::string(text.begin(), text.end()).substr(wordStart,wordLen));
+ std::string selectedWord(std::string(text.begin(), text.end()).substr(wordStart, wordLen));
if (!glggHunSpell->isSpelledRight(selectedWord))
{
//misspelled word here, and you have just right clicked on it!
std::vector suggs = glggHunSpell->getSuggestionList(selectedWord);
- for (int i = 0; i<(int)suggs.size(); i++)
+ menu->addSeparator();
+ for (auto word : suggs)
{
SpellMenuBind * tempStruct = new SpellMenuBind;
tempStruct->origin = this;
- tempStruct->word = suggs[i];
+ tempStruct->word = word;
tempStruct->wordPositionEnd = wordStart + wordLen;
- tempStruct->wordPositionStart=wordStart;
- tempStruct->wordY=y;
+ tempStruct->wordPositionStart = wordStart;
+ tempStruct->wordY = y;
LLMenuItemCallGL * suggMenuItem = new LLMenuItemCallGL(
tempStruct->word, spell_correct, NULL, tempStruct);
tempStruct->menuItem = suggMenuItem;
@@ -1431,8 +1543,8 @@ BOOL LLTextEditor::handleRightMouseDown( S32 x, S32 y, MASK mask )
tempStruct->origin = this;
tempStruct->word = selectedWord;
tempStruct->wordPositionEnd = wordStart + wordLen;
- tempStruct->wordPositionStart=wordStart;
- tempStruct->wordY=y;
+ tempStruct->wordPositionStart = wordStart;
+ tempStruct->wordY = y;
LLMenuItemCallGL * suggMenuItem = new LLMenuItemCallGL(
"Add Word", spell_add, NULL, tempStruct);
tempStruct->menuItem = suggMenuItem;
@@ -1446,11 +1558,11 @@ BOOL LLTextEditor::handleRightMouseDown( S32 x, S32 y, MASK mask )
if (glggHunSpell->getSpellCheckHighlight())
{
tempStruct->word = "Hide Misspellings";
- }
+ }
else
- {
+ {
tempStruct->word = "Show Misspellings";
- }
+ }
LLMenuItemCallGL * suggMenuItem = new LLMenuItemCallGL(
tempStruct->word, spell_show, NULL, tempStruct);
@@ -1458,6 +1570,7 @@ BOOL LLTextEditor::handleRightMouseDown( S32 x, S32 y, MASK mask )
suggestionMenuItems.push_back(tempStruct);
menu->addChild(suggMenuItem);
}
+
mLastContextMenuX = x;
mLastContextMenuY = y;
menu->buildDrawLabels();
@@ -1484,6 +1597,7 @@ BOOL LLTextEditor::handleHover(S32 x, S32 y, MASK mask)
{
BOOL handled = FALSE;
+ auto old_hover = mHoverSegment;
mHoverSegment = NULL;
if(hasMouseCapture() )
{
@@ -1568,6 +1682,14 @@ BOOL LLTextEditor::handleHover(S32 x, S32 y, MASK mask)
}
}
+ if (old_hover != mHoverSegment)
+ {
+ if (old_hover)
+ old_hover->underlineOnHover(false);
+ if (mHoverSegment)
+ mHoverSegment->underlineOnHover(true);
+ }
+
if (mOnScrollEndCallback && mOnScrollEndData && (mScrollbar->getDocPos() == mScrollbar->getDocPosMax()))
{
mOnScrollEndCallback(mOnScrollEndData);
@@ -1575,6 +1697,14 @@ BOOL LLTextEditor::handleHover(S32 x, S32 y, MASK mask)
return handled;
}
+void LLTextEditor::onMouseLeave(S32 x, S32 y, MASK mask)
+{
+ if (mHoverSegment)
+ {
+ mHoverSegment->underlineOnHover(false);
+ mHoverSegment = nullptr;
+ }
+}
BOOL LLTextEditor::handleMouseUp(S32 x, S32 y, MASK mask)
{
@@ -1733,11 +1863,6 @@ S32 LLTextEditor::remove(const S32 pos, const S32 length, const BOOL group_with_
return execute( new LLTextCmdRemove( pos, group_with_next_op, length ) );
}
-S32 LLTextEditor::append(const LLWString &wstr, const BOOL group_with_next_op)
-{
- return insert(mWText.length(), wstr, group_with_next_op);
-}
-
S32 LLTextEditor::overwriteChar(S32 pos, llwchar wc)
{
if ((S32)mWText.length() == pos)
@@ -2170,7 +2295,7 @@ BOOL LLTextEditor::canCopy() const
}
// copy selection to clipboard
-void LLTextEditor::copy()
+void LLTextEditor::copy(bool raw)
{
if( !canCopy() )
{
@@ -2178,7 +2303,54 @@ void LLTextEditor::copy()
}
S32 left_pos = llmin( mSelectionStart, mSelectionEnd );
S32 length = llabs( mSelectionStart - mSelectionEnd );
- gClipboard.copyFromSubstring(mWText, left_pos, length, mSourceID);
+ // Does our selection include any Segments with links?
+ if (mParseHTML && raw)
+ {
+ auto begin = std::find_if(mSegments.begin(), mSegments.end(), [left_pos](const LLTextSegmentPtr& ptr) {
+ return ptr->getEnd() > left_pos;
+ });
+ auto last = mSegments.end();
+ if (begin == last || begin->isNull())
+ {
+ gClipboard.copyFromSubstring(mWText, left_pos, length, mSourceID);
+ return;
+ }
+ S32 right_pos = left_pos + length, offset = 0;
+ {
+ // If our selection starts in the middle of a link, set our left_pos to the beginning of its segment.
+ auto segment = **begin;
+ if (auto style = segment.getStyle())
+ if (style->isLink())
+ left_pos = llmin(segment.getStart(), left_pos);
+ }
+ auto text = mWText.substr(left_pos, length);
+ for (; begin->notNull() && begin != last && (*begin)->getStart() <= right_pos; ++begin)
+ {
+ auto segment = **begin;
+ //llassert(segment->getStyle()); // If someone is stores the result of the S32 constructor, they're in so much trouble!!
+ const auto& link = segment.getStyle()->getLinkHREF();
+ if (!link.empty())
+ {
+ const S32 label_length = (segment.getEnd() - segment.getStart());
+ const S32 start = (segment.getStart()+offset)-left_pos;
+ const auto label = text.substr(start, label_length);
+ const auto wlink = utf8str_to_wstring(link);
+ const auto pos = wlink.find(label);
+ // Do not replace if normal link, or contains normal link (but may omit protocol) but ends the same way
+ // (i.e. [http://foo.bar/baz foo.bar] should still be restored here but not foo.bar/baz or foo.bar
+ if (pos == std::string::npos // Label is not (part of) the url
+ || (pos != 0 && wlink[pos-1] != '/') || pos+label.size() != wlink.size()) // Label is part of the url but there's more on either side of the url after the protocol
+ {
+ constexpr llwchar startchar = '[', space = ' ', endchar = ']';
+ const auto raw_html = startchar + wlink + space + label + endchar;
+ text.replace(start, label_length, raw_html);
+ offset += raw_html.size() - label_length; // Track how much we've offset the string by replacing labels with their raw html and thus adding characters
+ }
+ }
+ }
+ gClipboard.copyFromSubstring(text, 0, text.length(), mSourceID);
+ }
+ else gClipboard.copyFromSubstring(mWText, left_pos, length, mSourceID);
}
BOOL LLTextEditor::canPaste() const
@@ -2416,6 +2588,17 @@ BOOL LLTextEditor::handleEditKey(const KEY key, const MASK mask)
}
handled = TRUE;
}
+ else if ((mask & (MASK_CONTROL|MASK_SHIFT)) == (MASK_CONTROL|MASK_SHIFT))
+ {
+ if (key == 'C')
+ {
+ if (canCopy())
+ copy(true);
+ else
+ reportBadKeystroke();
+ handled = TRUE;
+ }
+ }
else
if( MASK_CONTROL & mask )
{
@@ -3446,12 +3629,14 @@ void LLTextEditor::drawText()
F32 text_y = (F32)(mTextRect.mTop - line_height);
while((mTextRect.mBottom <= text_y) && (cur_line < num_lines))
{
+ S32 next_line = cur_line + 1;
+
S32 next_start = -1;
S32 line_end = text_len;
- if ((cur_line + 1) < num_lines)
+ if (next_line < num_lines)
{
- next_start = getLineStart(cur_line + 1);
+ next_start = getLineStart(next_line);
line_end = next_start;
}
line_wraps = text[line_end-1] != '\n';
@@ -3487,6 +3672,7 @@ void LLTextEditor::drawText()
NULL); // max pixels
}
+ // draw a single line of text
S32 seg_start = line_start;
while( seg_start < line_end )
{
@@ -3521,13 +3707,6 @@ void LLTextEditor::drawText()
style->mUnderline = TRUE;
}
- S32 left_pos = llmin( mSelectionStart, mSelectionEnd );
-
- if ( (mParseHTML) && (left_pos > seg_start) && (left_pos < clipped_end) && mIsSelecting && (mSelectionStart == mSelectionEnd) )
- {
- mHTML = style->getLinkHREF();
- }
-
drawClippedSegment( text, seg_start, clipped_end, text_x, text_y, selection_left, selection_right, style, &text_x );
if( text_x == text_start && mShowLineNumbers )
@@ -4077,31 +4256,67 @@ void LLTextEditor::appendColoredText(const std::string &new_text,
style->setVisible(true);
style->setColor(lcolor);
style->setFontName(font_name);
- appendStyledText(new_text, allow_undo, prepend_newline, style);
+ appendText(new_text, allow_undo, prepend_newline, style);
}
-void LLTextEditor::appendStyledText(const std::string &new_text,
- bool allow_undo,
- bool prepend_newline,
- LLStyleSP stylep)
+static LLTrace::BlockTimerStatHandle FTM_APPEND_TEXT("Append Text");
+
+void LLTextEditor::appendText(const std::string &new_text, bool allow_undo, bool prepend_newline,
+ const LLStyleSP style, bool force_replace_links)
{
- S32 part = (S32)LLTextParser::WHOLE;
- if(mParseHTML)
+ LL_RECORD_BLOCK_TIME(FTM_APPEND_TEXT);
+ if (new_text.empty())
+ return;
+
+ std::string text = prepend_newline && !mWText.empty() ? ('\n' + new_text) : new_text;
+ appendTextImpl(text, style);
+
+ if (!allow_undo)
{
+ blockUndo();
+ }
+}
+static LLTrace::BlockTimerStatHandle FTM_PARSE_HTML("Parse HTML");
+
+// Appends new text to end of document
+void LLTextEditor::appendTextImpl(const std::string &new_text, const LLStyleSP style, bool force_replace_links)
+{
+ std::string text = new_text;
+ static const LLUICachedControl replace_links("SinguReplaceLinks");
+ force_replace_links = force_replace_links || replace_links;
+ bool is_link = style && style->isLink(); // Don't search for URLs inside a link segment (STORM-358).
+
+ S32 part = (S32)LLTextParser::WHOLE;
+ if (mReadOnly && mParseHTML && !is_link) // Singu Note: Do not replace html if the user is going to edit it. (Like in profiles)
+ {
+ LL_RECORD_BLOCK_TIME(FTM_PARSE_HTML);
S32 start=0,end=0;
- std::string text = new_text;
- while ( findHTML(text, &start, &end) )
+ LLUrlMatch match;
+ auto append_substr = [&](const size_t& pos, const size_t& count)
{
- LLStyleSP html(new LLStyle);
- html->setVisible(true);
- html->setColor(mLinkColor);
- if (stylep)
+ appendAndHighlightText(text.substr(pos, count), part, style);
+ };
+ auto append_link = [&](const std::string& link, LLStyleSP link_style)
+ {
+ if (style) // Respect styling
{
- html->setFontName(stylep->getFontString());
+ const auto& text_style = *style;
+ link_style->mItalic = text_style.mItalic;
+ link_style->mBold = text_style.mBold;
+ link_style->mUnderline = text_style.mUnderline;
}
- html->mUnderline = TRUE;
+ // Hack around colors looking bad on some backgrounds by allowing setting link color for this editor
+ if (mLinkColor) link_style->setColor(*mLinkColor);
+ appendAndHighlightText(link, part, link_style, true/*match.underlineOnHoverOnly()*/);
+ };
+ const auto&& cb = force_replace_links ? boost::bind(&LLTextEditor::replaceUrl, this, _1, _2, _3) : LLUrlLabelCallback::slot_function_type();
+ while (!text.empty() && LLUrlRegistry::instance().findUrl(text, match, cb))
+ {
+ start = match.getStart();
+ end = match.getEnd()+1;
+ // output the text before the Url
if (start > 0)
{
if (part == (S32)LLTextParser::WHOLE ||
@@ -4113,15 +4328,69 @@ void LLTextEditor::appendStyledText(const std::string &new_text,
{
part = (S32)LLTextParser::MIDDLE;
}
- std::string subtext=text.substr(0,start);
- appendHighlightedText(subtext,allow_undo, prepend_newline, part, stylep);
+ append_substr(0, start);
}
-
- html->setLinkHREF(text.substr(start,end-start));
- appendText(text.substr(start, end-start),allow_undo, prepend_newline, html);
- if (end < (S32)text.length())
+
+ auto url = match.getUrl();
+ const auto& label = match.getLabel();
+ if (force_replace_links || replace_links || url == label)
{
- text = text.substr(end,text.length() - end);
+ // add icon before url if need
+ /* Singu TODO: Icons next to links?
+ LLTextUtil::processUrlMatch(&match, this, isContentTrusted() || match.isTrusted());
+ if ((isContentTrusted() || match.isTrusted()) && !match.getIcon().empty() )
+ {
+ link_style->setImage(match.getIcon());
+ setLastSegmentToolTip(LLTrans::getString("TooltipSLIcon"));
+ }*/
+
+ // output the styled url
+ append_link(label + match.getQuery(), match.getStyle());
+ bool tooltip_required = !match.getTooltip().empty();
+
+ // set the tooltip for the Url label
+ if (tooltip_required)
+ {
+ setLastSegmentToolTip(match.getTooltip());
+ }
+
+ /* Singu Note: Upstream uses hardcoded Grey here, they have no care for skins, this could be awful!
+ Also it splits up the link! For now just make it append it to the same segment with its label above.
+ // show query part of url with gray color only for LLUrlEntryHTTP and LLUrlEntryHTTPNoProtocol url entries
+ std::string label = match.getQuery();
+ if (!label.empty())
+ {
+ link_params.color = LLColor4::grey;
+ link_params.readonly_color = LLColor4::grey;
+ appendAndHighlightTextImpl(label, part, link_params, match.underlineOnHoverOnly());
+ append_link(label);
+
+ // set the tooltip for the query part of url
+ if (tooltip_required)
+ {
+ setLastSegmentToolTip(match.getTooltip());
+ }
+ }*/
+ }
+ else // Still link the link itself
+ {
+ const auto pos = text.find(url);
+ bool fallback(pos == std::string::npos); // In special cases like no protocol and brackets
+ bool brackets(fallback && text.find('[') == start); // Brackets
+ if (fallback == brackets && start < pos) // Leading text, only in special case if brackets present
+ append_substr(start, brackets ? 1 : pos-start);
+ // In the special cases, only link exactly the url, this might not have a protocol so calculate the exact string
+ if (fallback) url = brackets ? text.substr(start+1, text.find(' ', start+2)-start) : text.substr(start, end-start);
+ append_link(url, match.getStyle()); // Append the link
+ const auto url_end = pos + url.size();
+ if (fallback == brackets && end > url_end) // Ending text, only in special case if brackets present
+ append_substr(url_end, end-url_end);
+ }
+
+ // move on to the rest of the text after the Url
+ if (end < (S32)text.length())
+ {
+ text = text.substr(end, text.length() - end);
end=0;
part=(S32)LLTextParser::END;
}
@@ -4130,51 +4399,123 @@ void LLTextEditor::appendStyledText(const std::string &new_text,
break;
}
}
- if (part != (S32)LLTextParser::WHOLE) part=(S32)LLTextParser::END;
- if (end < (S32)text.length()) appendHighlightedText(text,allow_undo, prepend_newline, part, stylep);
+ if (part != (S32)LLTextParser::WHOLE)
+ part=(S32)LLTextParser::END;
+ if (end < (S32)text.length())
+ appendAndHighlightText(text, part, style);
}
else
{
- appendHighlightedText(new_text, allow_undo, prepend_newline, part, stylep);
+ appendAndHighlightText(text, part, style);
}
}
-void LLTextEditor::appendHighlightedText(const std::string &new_text,
- bool allow_undo,
- bool prepend_newline,
- S32 highlight_part,
- LLStyleSP stylep)
+void LLTextEditor::setLastSegmentToolTip(const std::string &tooltip)
{
- // If LindenUserDir is empty then we didn't login yet.
- // In that case we can't instantiate LLTextParser, which
- // is initialized per user.
- if (mParseHighlights && !gDirUtilp->getLindenUserDir(true).empty())
- {
- LLTextParser* highlight = LLTextParser::getInstance();
-
- if (highlight && stylep)
- {
- LLSD pieces = highlight->parsePartialLineHighlights(new_text, stylep->getColor(), (LLTextParser::EHighlightPosition)highlight_part);
- bool lprepend=prepend_newline;
- for (S32 i=0;isetColor(lcolor);
- if (i != 0 && (pieces.size() > 1) ) lprepend=FALSE;
- appendText((std::string)pieces[i]["text"], allow_undo, lprepend, lstylep);
- }
- return;
- }
- }
- appendText(new_text, allow_undo, prepend_newline, stylep);
+ LLTextSegmentPtr segment = mSegments.back();
+ segment->setToolTip(tooltip);
}
-// Appends new text to end of document
-void LLTextEditor::appendText(const std::string &new_text, bool allow_undo, bool prepend_newline,
- const LLStyleSP stylep)
+void LLTextEditor::appendLineBreakSegment(/*const LLStyle::Params& style_params*/)
+{
+ /*
+ segment_vec_t segments;
+ LLStyleSP sp(new LLStyle(style_params));
+ const auto& length = getLength();
+ segments.push_back(new LLTextSegment(sp, length, length + 1));*/
+
+ insertStringNoUndo(getLength(), LLWString(1, '\n'));
+}
+
+void LLTextEditor::appendAndHighlightText(const std::string& new_text, S32 highlight_part, const LLStyleSP stylep, bool underline_on_hover)
+{
+ if (new_text.empty()) return;
+
+ std::string::size_type start = 0;
+ /*std::string::size_type pos = new_text.find('\n',start);
+
+ while(pos!=-1)
+ {
+ if(pos!=start)
+ {
+ std::string str = std::string(new_text,start,pos-start);
+ appendAndHighlightTextImpl(str,highlight_part, stylep);
+ }
+ appendLineBreakSegment();
+ start = pos+1;
+ pos = new_text.find('\n',start);
+ }*/
+
+ std::string str = std::string(new_text,start,new_text.length()-start);
+ appendAndHighlightTextImpl(str,highlight_part, stylep, underline_on_hover);
+}
+
+
+void LLTextEditor::replaceUrl(const std::string &url,
+ const std::string &label,
+ const std::string &icon)
+{
+ // get the full (wide) text for the editor so we can change it
+ LLWString text = getWText();
+ LLWString wlabel = utf8str_to_wstring(label);
+ bool modified = false;
+ S32 seg_start = 0;
+
+ // iterate through each segment looking for ones styled as links
+ for (auto it = mSegments.begin(); it != mSegments.end(); ++it)
+ {
+ LLTextSegment *seg = *it;
+ LLStyleSP style = seg->getStyle();
+
+ // update segment start/end length in case we replaced text earlier
+ S32 seg_length = seg->getEnd() - seg->getStart();
+ seg->setStart(seg_start);
+ seg->setEnd(seg_start + seg_length);
+
+ // if we find a link with our Url, then replace the label
+ if (style->getLinkHREF() == url)
+ {
+ S32 start = seg->getStart();
+ S32 end = seg->getEnd();
+ text = text.substr(0, start) + wlabel + text.substr(end, text.size() - end + 1);
+ seg->setEnd(start + wlabel.size());
+ modified = true;
+ }
+
+ /* Singu TODO: Icons with Urls?
+ // Icon might be updated when more avatar or group info
+ // becomes available
+ if (style->isImage() && style->getLinkHREF() == url)
+ {
+ LLUIImagePtr image = image_from_icon_name( icon );
+ if (image)
+ {
+ LLStyle::Params icon_params;
+ icon_params.image = image;
+ LLStyleConstSP new_style(new LLStyle(icon_params));
+ seg->setStyle(new_style);
+ modified = true;
+ }
+ }
+ */
+
+ // work out the character offset for the next segment
+ seg_start = seg->getEnd();
+ }
+
+ // update the editor with the new (wide) text string
+ if (modified)
+ {
+ mWText = text;
+ mTextIsUpToDate = FALSE;
+ deselect();
+ setCursorPos(mCursorPos);
+ needsReflow();
+ }
+}
+
+
+void LLTextEditor::appendAndHighlightTextImpl(const std::string& new_text, S32 highlight_part, const LLStyleSP stylep, bool underline_on_hover)
{
// Save old state
BOOL was_scrolled_to_bottom = (mScrollbar->getDocPos() == mScrollbar->getDocPosMax());
@@ -4189,29 +4530,71 @@ void LLTextEditor::appendText(const std::string &new_text, bool allow_undo, bool
setCursorPos(old_length);
- // Add carriage return if not first line
- if (getLength() != 0
- && prepend_newline)
+ // This is where we appendHighlightedText
+ // If LindenUserDir is empty then we didn't login yet.
+ // In that case we can't instantiate LLTextParser, which is initialized per user.
+ if (mParseHighlights && !gDirUtilp->getLindenUserDir(true).empty())
{
- std::string final_text = "\n";
- final_text += new_text;
- append(utf8str_to_wstring(final_text), TRUE);
+ LLTextParser* highlight = LLTextParser::getInstance();
+
+ if (highlight && stylep)
+ {
+ LLStyleSP highlight_params(new LLStyle(*stylep));
+ LLSD pieces = highlight->parsePartialLineHighlights(new_text, highlight_params->getColor(), (LLTextParser::EHighlightPosition)highlight_part);
+ for (S32 i=0;isetColor(lcolor);
+
+ LLWString wide_text;
+ wide_text = utf8str_to_wstring(pieces[i]["text"].asString());
+
+ S32 cur_length = getLength();
+ insertStringNoUndo(cur_length, wide_text);
+ LLStyleSP sp(new LLStyle(*highlight_params));
+ LLTextSegmentPtr segmentp;
+ segmentp = new LLTextSegment(sp, cur_length, cur_length + wide_text.size());
+ if (underline_on_hover) segmentp->setUnderlineOnHover(true);
+ mSegments.push_back(segmentp);
+ }
+ return;
+ }
}
- else
+ //else
{
- append(utf8str_to_wstring(new_text), TRUE );
+ LLWString wide_text;
+ wide_text = utf8str_to_wstring(new_text);
+
+ auto length = getLength();
+ auto insert_len = length + insertStringNoUndo(length, utf8str_to_wstring(new_text));
+
+ if (stylep)
+ {
+ S32 segment_start = old_length;
+ S32 segment_end = old_length + wide_text.size();
+ LLTextSegmentPtr segment = new LLTextSegment(stylep, segment_start, segment_end);
+ if (underline_on_hover) segment->setUnderlineOnHover(true);
+ mSegments.push_back(segment);
+ }
+ else // If no style, still make a segment,
+ {
+ auto segment = mSegments.empty() ? nullptr : mSegments.back();
+ if (!segment || !segment->getIsDefault())
+ {
+ LLColor4& text_color = (mReadOnly ? mReadOnlyFgColor : mFgColor);
+ LLTextSegmentPtr segment = new LLTextSegment(text_color, length, insert_len);
+ segment->setIsDefault(true); // call it a default segment so we can consolidate later.
+ mSegments.push_back(segment);
+ }
+ else // It's later!
+ {
+ segment->setEnd(insert_len);
+ }
+ }
}
- if (stylep)
- {
- S32 segment_start = old_length;
- S32 segment_end = getLength();
- LLTextSegmentPtr segment = new LLTextSegment(stylep, segment_start, segment_end );
- mSegments.push_back(segment);
- }
-
- needsReflow();
-
// Set the cursor and scroll position
// Maintain the scroll position unless the scroll was at the end of the doc (in which
// case, move it to the new end of the doc) or unless the user was doing actively selecting
@@ -4230,9 +4613,6 @@ void LLTextEditor::appendText(const std::string &new_text, bool allow_undo, bool
mSelectionStart = selection_start;
mSelectionEnd = selection_end;
-
-
-
mIsSelecting = was_selecting;
setCursorPos(cursor_pos);
}
@@ -4244,11 +4624,6 @@ void LLTextEditor::appendText(const std::string &new_text, bool allow_undo, bool
{
setCursorPos(cursor_pos);
}
-
- if( !allow_undo )
- {
- blockUndo();
- }
}
void LLTextEditor::removeTextFromEnd(S32 num_chars)
@@ -4281,13 +4656,16 @@ S32 LLTextEditor::insertStringNoUndo(const S32 pos, const LLWString &wstr)
mWText.insert(pos, wstr);
mTextIsUpToDate = FALSE;
- if ( truncate() )
+ //HACK: If we are readonly we shouldn't need to truncate
+ if (!mReadOnly && truncate())
{
// The user's not getting everything he's hoping for
make_ui_sound("UISndBadKeystroke");
insert_len = mWText.length() - old_len;
}
+ needsReflow(/*pos*/);
+
return insert_len;
}
@@ -4409,6 +4787,25 @@ void LLTextEditor::loadKeywords(const std::string& filename,
static LLTrace::BlockTimerStatHandle FTM_SYNTAX_HIGHLIGHTING("Syntax Highlighting");
static LLTrace::BlockTimerStatHandle FTM_UPDATE_TEXT_SEGMENTS("Update Text Segments");
+
+void LLTextEditor::createDefaultSegment()
+{
+ if (mSegments.empty())
+ {
+ LLColor4& text_color = (mReadOnly ? mReadOnlyFgColor : mFgColor);
+ LLTextSegmentPtr default_segment = new LLTextSegment(text_color, 0, mWText.length());
+ default_segment->setIsDefault(TRUE);
+ mSegments.push_back(default_segment);
+ }
+}
+
+void LLTextEditor::clearSegments()
+{
+ mLineStartList.clear();
+ mSegments.clear();
+ createDefaultSegment();
+}
+
void LLTextEditor::updateSegments()
{
{
@@ -4428,15 +4825,9 @@ void LLTextEditor::updateSegments()
// Make sure we have at least one segment
if (mSegments.size() == 1 && mSegments[0]->getIsDefault())
{
- mSegments.clear(); // create default segment
- }
- if (mSegments.empty())
- {
- LLColor4& text_color = ( mReadOnly ? mReadOnlyFgColor : mFgColor );
- LLTextSegmentPtr default_segment = new LLTextSegment( text_color, 0, mWText.length() );
- default_segment->setIsDefault(TRUE);
- mSegments.push_back(default_segment);
+ clearSegments(); // create default segment
}
+ else createDefaultSegment();
}
// Only effective if text was removed from the end of the editor
@@ -4539,10 +4930,16 @@ BOOL LLTextEditor::handleMouseUpOverSegment(S32 x, S32 y, MASK mask)
// This mouse up was part of a click.
// Regardless of where the cursor is, see if we recently touched a link
// and launch it if we did.
- if (mParseHTML && mHTML.length() > 0)
+ if (mParseHTML)
{
- LLUrlAction::clickAction(mHTML);
- mHTML.clear();
+ if (auto segment = getSegmentAtLocalPos(x, y))
+ {
+ if (auto style = segment->getStyle())
+ {
+ if (style->isLink())
+ LLUrlAction::clickAction(style->getLinkHREF(), true);
+ }
+ }
}
}
@@ -4695,6 +5092,24 @@ BOOL LLTextEditor::exportBuffer(std::string &buffer )
return TRUE;
}
+boost::signals2::connection LLTextEditor::setIsFriendCallback(const is_friend_signal_t::slot_type& cb)
+{
+ if (!mIsFriendSignal)
+ {
+ mIsFriendSignal = new is_friend_signal_t();
+ }
+ return mIsFriendSignal->connect(cb);
+}
+
+boost::signals2::connection LLTextEditor::setIsObjectBlockedCallback(const is_blocked_signal_t::slot_type& cb)
+{
+ if (!mIsObjectBlockedSignal)
+ {
+ mIsObjectBlockedSignal = new is_blocked_signal_t();
+ }
+ return mIsObjectBlockedSignal->connect(cb);
+}
+
//////////////////////////////////////////////////////////////////////////
// LLTextSegment
@@ -4740,15 +5155,34 @@ LLTextSegment::LLTextSegment( const LLColor3& color, S32 start, S32 end ) :
BOOL LLTextSegment::getToolTip(std::string& msg) const
{
+ // do we have a tooltip for a loaded keyword (for script editor)?
if (mToken && !mToken->getToolTip().empty())
{
const LLWString& wmsg = mToken->getToolTip();
msg = wstring_to_utf8str(wmsg);
return TRUE;
}
+ // or do we have an explicitly set tooltip (e.g., for Urls)
+ if (!mTooltip.empty())
+ {
+ msg = mTooltip;
+ return TRUE;
+ }
+
return FALSE;
}
+void LLTextSegment::setToolTip(const std::string& tooltip)
+{
+ // we cannot replace a keyword tooltip that's loaded from a file
+ if (mToken)
+ {
+ LL_WARNS() << "LLTextSegment::setToolTip: cannot replace keyword tooltip." << LL_ENDL;
+ return;
+ }
+ mTooltip = tooltip;
+}
+
void LLTextSegment::dump() const
@@ -4777,6 +5211,7 @@ LLXMLNodePtr LLTextEditor::getXML(bool save_children) const
node->createChild("font", TRUE)->setStringValue(LLFontGL::nameFromFont(mGLFont));
node->createChild("word_wrap", TRUE)->setBoolValue(mWordWrap);
node->createChild("hide_scrollbar", TRUE)->setBoolValue(mHideScrollbarForShortDocs);
+ node->createChild("hide_border", TRUE)->setBoolValue(!mBorder->getVisible());
addColorXML(node, mCursorColor, "cursor_color", "TextCursorColor");
addColorXML(node, mFgColor, "text_color", "TextFgColor");
@@ -4827,173 +5262,6 @@ void LLTextEditor::setTextEditorParameters(LLXMLNodePtr node)
}
}
-///////////////////////////////////////////////////////////////////
-// Refactoring note: We may eventually want to replace this with boost::regex or
-// boost::tokenizer capabilities since we've already fixed at least two JIRAs
-// concerning logic issues associated with this function.
-S32 LLTextEditor::findHTMLToken(const std::string &line, S32 pos, BOOL reverse) const
-{
- std::string openers=" \t\n('\"[{<>";
- std::string closers=" \t\n)'\"]}><;";
-
- if (reverse)
- {
- for (int index=pos; index >= 0; index--)
- {
- char c = line[index];
- S32 m2 = openers.find(c);
- if (m2 >= 0)
- {
- return index+1;
- }
- }
- return 0; // index is -1, don't want to return that.
- }
- else
- {
- // adjust the search slightly, to allow matching parenthesis inside the URL
- S32 paren_count = 0;
- for (int index=pos; index<(S32)line.length(); index++)
- {
- char c = line[index];
-
- if (c == '(')
- {
- paren_count++;
- }
- else if (c == ')')
- {
- if (paren_count <= 0)
- {
- return index;
- }
- else
- {
- paren_count--;
- }
- }
- else
- {
- S32 m2 = closers.find(c);
- if (m2 >= 0)
- {
- return index;
- }
- }
- }
- return line.length();
- }
-}
-
-BOOL LLTextEditor::findHTML(const std::string &line, S32 *begin, S32 *end) const
-{
-
- S32 m1,m2,m3;
- BOOL matched = FALSE;
-
- m1=line.find("://",*end);
-
- if (m1 >= 0) //Easy match.
- {
- *begin = findHTMLToken(line, m1, TRUE);
- *end = findHTMLToken(line, m1, FALSE);
-
- //Load_url only handles http and https so don't hilite ftp, smb, etc.
- m2 = line.substr(*begin,(m1 - *begin)).find("http");
- m3 = line.substr(*begin,(m1 - *begin)).find("secondlife");
-
- std::string badneighbors=".,<>?';\"][}{=-+_)(*&^%$#@!~`\t\r\n\\";
-
- if (m2 >= 0 || m3>=0)
- {
- S32 bn = badneighbors.find(line.substr(m1+3,1));
-
- if (bn < 0)
- {
- matched = TRUE;
- }
- }
- }
-/* matches things like secondlife.com (no http://) needs a whitelist to really be effective.
- else //Harder match.
- {
- m1 = line.find(".",*end);
-
- if (m1 >= 0)
- {
- *end = findHTMLToken(line, m1, FALSE);
- *begin = findHTMLToken(line, m1, TRUE);
-
- m1 = line.rfind(".",*end);
-
- if ( ( *end - m1 ) > 2 && m1 > *begin)
- {
- std::string badneighbors=".,<>/?';\"][}{=-+_)(*&^%$#@!~`";
- m2 = badneighbors.find(line.substr(m1+1,1));
- m3 = badneighbors.find(line.substr(m1-1,1));
- if (m3<0 && m2<0)
- {
- matched = TRUE;
- }
- }
- }
- }
- */
-
- if (matched)
- {
- S32 strpos, strpos2;
-
- std::string url = line.substr(*begin,*end - *begin);
- std::string slurlID = "slurl.com/secondlife/";
- strpos = url.find(slurlID);
-
- if (strpos < 0)
- {
- slurlID="maps.secondlife.com/secondlife/";
- strpos = url.find(slurlID);
- }
-
- if (strpos < 0)
- {
- slurlID="secondlife://";
- strpos = url.find(slurlID);
- }
-
- if (strpos < 0)
- {
- slurlID="sl://";
- strpos = url.find(slurlID);
- }
-
- if (strpos >= 0)
- {
- strpos+=slurlID.length();
-
- while ( ( strpos2=url.find("/",strpos) ) == -1 )
- {
- if ((*end+2) >= (S32)line.length() || line.substr(*end,1) != " " )
- {
- matched=FALSE;
- break;
- }
-
- strpos = (*end + 1) - *begin;
-
- *end = findHTMLToken(line,(*begin + strpos),FALSE);
- url = line.substr(*begin,*end - *begin);
- }
- }
-
- }
-
- if (!matched)
- {
- *begin=*end=0;
- }
- return matched;
-}
-
void LLTextEditor::updateAllowingLanguageInput()
diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h
index 3bfdfb6d6..1bac9702c 100644
--- a/indra/llui/lltexteditor.h
+++ b/indra/llui/lltexteditor.h
@@ -65,14 +65,22 @@ public:
LLTextEditor(const std::string& name,
const LLRect& rect,
S32 max_length,
- const std::string &default_text,
+ const std::string &default_text,
const LLFontGL* glfont = NULL,
- BOOL allow_embedded_items = FALSE);
+ BOOL allow_embedded_items = FALSE,
+ bool parse_html = false);
virtual ~LLTextEditor();
- typedef boost::signals2::signal keystroke_signal_t;
+ const std::string& getMenuSegmentUrl() const;
+ typedef boost::signals2::signal keystroke_signal_t;
+ typedef boost::signals2::signal is_friend_signal_t;
+ typedef boost::signals2::signal is_blocked_signal_t;
+
+ 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();
void setKeystrokeCallback(const keystroke_signal_t::slot_type& callback);
virtual LLXMLNodePtr getXML(bool save_children = true) const;
@@ -84,6 +92,7 @@ public:
virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask);
virtual BOOL handleHover(S32 x, S32 y, MASK mask);
+ virtual void onMouseLeave(S32 x, S32 y, MASK mask) override;
virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
virtual BOOL handleDoubleClick(S32 x, S32 y, MASK mask );
virtual BOOL handleRightMouseDown( S32 x, S32 y, MASK mask );
@@ -131,7 +140,9 @@ public:
virtual BOOL canRedo() const;
virtual void cut();
virtual BOOL canCut() const;
- virtual void copy();
+ void copy(bool raw);
+ void copyRaw() { copy(true); }
+ virtual void copy() { copy(false); }
virtual BOOL canCopy() const;
virtual void paste();
virtual BOOL canPaste() const;
@@ -149,12 +160,6 @@ public:
virtual BOOL canSelectAll() const;
virtual void deselect();
virtual BOOL canDeselect() const;
- static void context_cut(void* data);
-
- static void context_copy(void* data);
- static void context_paste(void* data);
- static void context_delete(void* data);
- static void context_selectall(void* data);
static void spell_correct(void* data);
static void spell_add(void* data);
static void spell_show(void* data);
@@ -176,20 +181,24 @@ public:
void insertText(const std::string &text, BOOL deleteSelection = TRUE);
// appends text at end
void appendText(const std::string &wtext, bool allow_undo, bool prepend_newline,
- const LLStyleSP stylep = NULL);
+ const LLStyleSP stylep = NULL, bool force_replace_links = true);
+ void appendTextImpl(const std::string& new_text, const LLStyleSP style, bool force_replace_links = true);
+
+ void setLastSegmentToolTip(const std::string& tooltip);
+
+ void appendLineBreakSegment();
+
+ void appendAndHighlightText(const std::string& new_text, S32 highlight_part, const LLStyleSP stylep, bool underline_on_hover = false);
+
+ void replaceUrl(const std::string& url, const std::string& label, const std::string& icon);
void appendColoredText(const std::string &wtext, bool allow_undo,
bool prepend_newline,
const LLColor4 &color,
const std::string& font_name = LLStringUtil::null);
- // if styled text starts a line, you need to prepend a newline.
- void appendStyledText(const std::string &new_text, bool allow_undo,
- bool prepend_newline,
- LLStyleSP stylep = NULL);
- void appendHighlightedText(const std::string &new_text, bool allow_undo,
- bool prepend_newline, S32 highlight_part,
- LLStyleSP stylep);
+ void appendAndHighlightTextImpl(const std::string& new_text, S32 highlight_part, const LLStyleSP stylep, bool underline_on_hover = false);
+
// Removes text from the end of document
// Does not change highlight or cursor position.
void removeTextFromEnd(S32 num_chars);
@@ -253,8 +262,8 @@ public:
void setHandleEditKeysDirectly( BOOL b ) { mHandleEditKeysDirectly = b; }
- // Callbacks
- static void setLinkColor(LLColor4 color) { mLinkColor = color; }
+ // Use for when the link color needs to be changed to avoid looking awful
+ void setLinkColor(LLColor4* color) { if (mLinkColor) delete mLinkColor; mLinkColor = color; }
void setOnScrollEndCallback(void (*callback)(void*), void* userdata);
@@ -263,7 +272,9 @@ public:
LLSD getValue() const;
const std::string& getText() const;
-
+
+ LLMenuGL* createUrlContextMenu(S32 x, S32 y, const std::string &url); // create a popup context menu for the given Url
+
// Non-undoable
void setText(const LLStringExplicit &utf8str);
void setWText(const LLWString &wtext);
@@ -284,6 +295,7 @@ public:
llwchar getWChar(S32 pos) const { return mWText[pos]; }
LLWString getWSubString(S32 pos, S32 len) const { return mWText.substr(pos, len); }
+ const LLTextSegment* getLastSegment() const { return mSegments.empty() ? nullptr : mSegments.back(); }
const LLTextSegment* getCurrentSegment() const { return getSegmentAtOffset(mCursorPos); }
const LLTextSegment* getPreviousSegment() const;
void getSelectedSegments(std::vector& segments) const;
@@ -308,7 +320,6 @@ protected:
void updateTextRect();
const LLRect& getTextRect() const { return mTextRect; }
- void assignEmbedded(const std::string &s);
BOOL truncate(); // Returns true if truncation occurs
void removeCharOrTab();
@@ -364,9 +375,6 @@ protected:
virtual llwchar pasteEmbeddedItem(llwchar ext_char) { return ext_char; }
virtual void bindEmbeddedChars(const LLFontGL* font) const {}
virtual void unbindEmbeddedChars(const LLFontGL* font) const {}
-
- S32 findHTMLToken(const std::string &line, S32 pos, BOOL reverse) const;
- BOOL findHTML(const std::string &line, S32 *begin, S32 *end) const;
// Abstract inner base class representing an undoable editor command.
// Concrete sub-classes can be defined for operations such as insert, remove, etc.
@@ -408,7 +416,6 @@ protected:
void removeWord(bool prev);
S32 insert(const S32 pos, const LLWString &wstr, const BOOL group_with_next_op);
S32 remove(const S32 pos, const S32 length, const BOOL group_with_next_op);
- S32 append(const LLWString &wstr, const BOOL group_with_next_op);
// Direct operations
S32 insertStringNoUndo(S32 pos, const LLWString &wstr); // returns num of chars actually inserted
@@ -454,7 +461,6 @@ protected:
BOOL mParseHTML;
BOOL mParseHighlights;
- std::string mHTML;
typedef std::vector segment_list_t;
segment_list_t mSegments;
@@ -467,6 +473,10 @@ protected:
void (*mOnScrollEndCallback)(void*);
void *mOnScrollEndData;
+ // Used to check if user with given ID is avatar's friend
+ static is_friend_signal_t* mIsFriendSignal;
+ static is_blocked_signal_t* mIsObjectBlockedSignal;
+
LLWString mPreeditWString;
LLWString mPreeditOverwrittenWString;
std::vector mPreeditPositions;
@@ -480,6 +490,8 @@ private:
void pasteHelper(bool is_primary);
void onKeyStroke();
+ void createDefaultSegment();
+ void clearSegments();
void updateSegments();
void pruneSegments();
@@ -502,7 +514,7 @@ private:
// Data
//
LLKeywords mKeywords;
- static LLColor4 mLinkColor;
+ LLColor4* mLinkColor;
// Concrete LLTextCmd sub-classes used by the LLTextEditor base class
class LLTextCmdInsert;
@@ -615,6 +627,7 @@ public:
LLTextSegment( const LLColor3& color, S32 start, S32 end );
S32 getStart() const { return mStart; }
+ void setStart(S32 start) { mStart = start; }
S32 getEnd() const { return mEnd; }
void setEnd( S32 end ) { mEnd = end; }
const LLColor4& getColor() const { return mStyle->getColor(); }
@@ -623,9 +636,12 @@ public:
void setStyle(const LLStyleSP &style) { mStyle = style; }
void setIsDefault(BOOL b) { mIsDefault = b; }
BOOL getIsDefault() const { return mIsDefault; }
+ void setUnderlineOnHover(bool b) { mUnderlineOnHover = b; }
+ void underlineOnHover(bool hover) { if (mUnderlineOnHover) mStyle->mUnderline = hover; }
void setToken( LLKeywordToken* token ) { mToken = token; }
LLKeywordToken* getToken() const { return mToken; }
BOOL getToolTip( std::string& msg ) const;
+ void setToolTip(const std::string& tooltip);
void dump() const;
@@ -643,6 +659,8 @@ private:
S32 mEnd;
LLKeywordToken* mToken;
BOOL mIsDefault;
+ bool mUnderlineOnHover = false;
+ std::string mTooltip;
};
diff --git a/indra/llui/lluictrl.cpp b/indra/llui/lluictrl.cpp
index 6ff4260bd..26acc25da 100644
--- a/indra/llui/lluictrl.cpp
+++ b/indra/llui/lluictrl.cpp
@@ -38,6 +38,9 @@
static LLRegisterWidget r("ui_ctrl");
+F32 LLUICtrl::sActiveControlTransparency = 1.0f;
+F32 LLUICtrl::sInactiveControlTransparency = 1.0f;
+
LLUICtrl::CallbackParam::CallbackParam()
: name("name"),
function_name("function"),
@@ -94,25 +97,26 @@ const LLUICtrl::Params& LLUICtrl::getDefaultParams()
LLUICtrl::LLUICtrl(const LLUICtrl::Params& p, const LLViewModelPtr& viewmodel)
: LLView(p),
+ mCommitSignal(nullptr),
+ mValidateSignal(nullptr),
+ mMouseEnterSignal(nullptr),
+ mMouseLeaveSignal(nullptr),
+ mMouseDownSignal(nullptr),
+ mMouseUpSignal(nullptr),
+ mRightMouseDownSignal(nullptr),
+ mRightMouseUpSignal(nullptr),
+ mDoubleClickSignal(nullptr),
+ mViewModel(viewmodel),
+ mEnabledControlVariable(nullptr),
+ mDisabledControlVariable(nullptr),
+ mMakeVisibleControlVariable(nullptr),
+ mMakeInvisibleControlVariable(nullptr),
mIsChrome(FALSE),
mRequestsFront(p.requests_front),
mTabStop(TRUE),
mTentative(FALSE),
- mViewModel(viewmodel),
- mEnabledControlVariable(NULL),
- mDisabledControlVariable(NULL),
- mMakeVisibleControlVariable(NULL),
- mMakeInvisibleControlVariable(NULL),
- mCommitSignal(NULL),
- mValidateSignal(NULL),
- mMouseEnterSignal(NULL),
- mMouseLeaveSignal(NULL),
- mMouseDownSignal(NULL),
- mMouseUpSignal(NULL),
- mRightMouseDownSignal(NULL),
- mRightMouseUpSignal(NULL),
- mDoubleClickSignal(NULL),
- mCommitOnReturn(FALSE)
+ mCommitOnReturn(FALSE),
+ mTransparencyType(TT_DEFAULT)
{
}
@@ -210,20 +214,21 @@ LLUICtrl::LLUICtrl(const std::string& name, const LLRect rect, BOOL mouse_opaque
mTabStop( TRUE ),
mTentative( FALSE ),
mViewModel(LLViewModelPtr(new LLViewModel)),
- mEnabledControlVariable(NULL),
- mDisabledControlVariable(NULL),
- mMakeVisibleControlVariable(NULL),
- mMakeInvisibleControlVariable(NULL),
- mCommitSignal(NULL),
- mValidateSignal(NULL),
- mMouseEnterSignal(NULL),
- mMouseLeaveSignal(NULL),
- mMouseDownSignal(NULL),
- mMouseUpSignal(NULL),
- mRightMouseDownSignal(NULL),
- mRightMouseUpSignal(NULL),
- mDoubleClickSignal(NULL),
- mCommitOnReturn(FALSE)
+ mEnabledControlVariable(nullptr),
+ mDisabledControlVariable(nullptr),
+ mMakeVisibleControlVariable(nullptr),
+ mMakeInvisibleControlVariable(nullptr),
+ mCommitSignal(nullptr),
+ mValidateSignal(nullptr),
+ mMouseEnterSignal(nullptr),
+ mMouseLeaveSignal(nullptr),
+ mMouseDownSignal(nullptr),
+ mMouseUpSignal(nullptr),
+ mRightMouseDownSignal(nullptr),
+ mRightMouseUpSignal(nullptr),
+ mDoubleClickSignal(nullptr),
+ mCommitOnReturn(FALSE),
+ mTransparencyType(TT_DEFAULT)
{
if(commit_callback)
setCommitCallback(commit_callback);
@@ -338,6 +343,8 @@ BOOL LLUICtrl::handleMouseDown(S32 x, S32 y, MASK mask)
{
(*mMouseDownSignal)(this,x,y,mask);
}
+ LL_DEBUGS() << "LLUICtrl::handleMousedown - handled is returning as: " << handled << " " << LL_ENDL;
+
return handled;
}
@@ -349,6 +356,7 @@ BOOL LLUICtrl::handleMouseUp(S32 x, S32 y, MASK mask)
{
(*mMouseUpSignal)(this,x,y,mask);
}
+
return handled;
}
@@ -466,7 +474,7 @@ void LLUICtrl::setEnabledControlVariable(LLControlVariable* control)
if (mEnabledControlVariable)
{
mEnabledControlConnection.disconnect(); // disconnect current signal
- mEnabledControlVariable = NULL;
+ mEnabledControlVariable = nullptr;
}
if (control)
{
@@ -481,7 +489,7 @@ void LLUICtrl::setDisabledControlVariable(LLControlVariable* control)
if (mDisabledControlVariable)
{
mDisabledControlConnection.disconnect(); // disconnect current signal
- mDisabledControlVariable = NULL;
+ mDisabledControlVariable = nullptr;
}
if (control)
{
@@ -496,7 +504,7 @@ void LLUICtrl::setMakeVisibleControlVariable(LLControlVariable* control)
if (mMakeVisibleControlVariable)
{
mMakeVisibleControlConnection.disconnect(); // disconnect current signal
- mMakeVisibleControlVariable = NULL;
+ mMakeVisibleControlVariable = nullptr;
}
if (control)
{
@@ -511,7 +519,7 @@ void LLUICtrl::setMakeInvisibleControlVariable(LLControlVariable* control)
if (mMakeInvisibleControlVariable)
{
mMakeInvisibleControlConnection.disconnect(); // disconnect current signal
- mMakeInvisibleControlVariable = NULL;
+ mMakeInvisibleControlVariable = nullptr;
}
if (control)
{
@@ -526,7 +534,12 @@ bool LLUICtrl::controlListener(const LLSD& newvalue, LLHandle handle,
LLUICtrl* ctrl = handle.get();
if (ctrl)
{
- if (type == "enabled")
+ if (type == "value")
+ {
+ ctrl->setValue(newvalue);
+ return true;
+ }
+ else if (type == "enabled")
{
ctrl->setEnabled(newvalue.asBoolean());
return true;
@@ -565,19 +578,19 @@ BOOL LLUICtrl::setLabelArg( const std::string& key, const LLStringExplicit& text
// virtual
LLCtrlSelectionInterface* LLUICtrl::getSelectionInterface()
{
- return NULL;
+ return nullptr;
}
// virtual
LLCtrlListInterface* LLUICtrl::getListInterface()
{
- return NULL;
+ return nullptr;
}
// virtual
LLCtrlScrollInterface* LLUICtrl::getScrollInterface()
{
- return NULL;
+ return nullptr;
}
BOOL LLUICtrl::hasFocus() const
@@ -603,7 +616,7 @@ void LLUICtrl::setFocus(BOOL b)
{
if( gFocusMgr.childHasKeyboardFocus(this))
{
- gFocusMgr.setKeyboardFocus( NULL );
+ gFocusMgr.setKeyboardFocus(nullptr );
}
}
}
@@ -1008,11 +1021,11 @@ LLUICtrl* LLUICtrl::getParentUICtrl() const
}
// *TODO: Deprecate; for backwards compatability only:
-boost::signals2::connection LLUICtrl::setCommitCallback( boost::function cb, void* data)
+boost::signals2::connection LLUICtrl::setCommitCallback( std::function cb, void* data)
{
return setCommitCallback( boost::bind(cb, _1, data));
}
-boost::signals2::connection LLUICtrl::setValidateBeforeCommit( boost::function cb )
+boost::signals2::connection LLUICtrl::setValidateBeforeCommit( std::function cb )
{
if (!mValidateSignal) mValidateSignal = new enable_signal_t();
return mValidateSignal->connect(boost::bind(cb, _2));
@@ -1030,7 +1043,6 @@ BOOL LLUICtrl::getTentative() const
return mTentative;
}
-
// virtual
void LLUICtrl::setColor(const LLColor4& color)
{ }
@@ -1047,6 +1059,37 @@ void LLUICtrl::setMinValue(LLSD min_value)
void LLUICtrl::setMaxValue(LLSD max_value)
{ }
+F32 LLUICtrl::getCurrentTransparency()
+{
+ F32 alpha = 0;
+
+ switch(mTransparencyType)
+ {
+ case TT_DEFAULT:
+ alpha = getDrawContext().mAlpha;
+ break;
+
+ case TT_ACTIVE:
+ alpha = sActiveControlTransparency;
+ break;
+
+ case TT_INACTIVE:
+ alpha = sInactiveControlTransparency;
+ break;
+
+ case TT_FADING:
+ alpha = sInactiveControlTransparency / 2.f;
+ break;
+ }
+
+ return alpha;
+}
+
+void LLUICtrl::setTransparencyType(ETypeTransparency type)
+{
+ mTransparencyType = type;
+}
+
boost::signals2::connection LLUICtrl::setCommitCallback(const CommitCallbackParam& cb)
{
return setCommitCallback(initCommitCallback(cb));
diff --git a/indra/llui/lluictrl.h b/indra/llui/lluictrl.h
index ca0e11d16..ff28f2519 100644
--- a/indra/llui/lluictrl.h
+++ b/indra/llui/lluictrl.h
@@ -34,16 +34,11 @@
#ifndef LL_LLUICTRL_H
#define LL_LLUICTRL_H
+//#include "llboost.h"
#include "llrect.h"
#include "llsd.h"
#include "llregistry.h"
-#ifndef BOOST_FUNCTION_HPP_INCLUDED
-#include
-#define BOOST_FUNCTION_HPP_INCLUDED
-#endif
-#include
-
#include "llinitparam.h"
#include "llview.h"
#include "llviewmodel.h" // *TODO move dependency to .cpp file
@@ -128,6 +123,13 @@ public:
Params();
};
+ enum ETypeTransparency
+ {
+ TT_DEFAULT,
+ TT_ACTIVE, // focused floater
+ TT_INACTIVE, // other floaters
+ TT_FADING, // fading toast
+ };
/*virtual*/ ~LLUICtrl();
void initFromParams(const Params& p);
@@ -147,26 +149,26 @@ public:
// We shouldn't ever need to set this directly
//virtual void setViewModel(const LLViewModelPtr&);
- virtual BOOL postBuild();
+ BOOL postBuild() override;
public:
// LLView interface
/*virtual*/ void initFromXML(LLXMLNodePtr node, LLView* parent);
/*virtual*/ LLXMLNodePtr getXML(bool save_children = true) const;
- /*virtual*/ BOOL setLabelArg( const std::string& key, const LLStringExplicit& text );
- /*virtual*/ BOOL isCtrl() const;
- /*virtual*/ void onMouseEnter(S32 x, S32 y, MASK mask);
- /*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask);
- /*virtual*/ BOOL canFocusChildren() const;
- /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask);
- /*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask);
- /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
- /*virtual*/ BOOL handleRightMouseUp(S32 x, S32 y, MASK mask);
- /*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask);
+ /*virtual*/ BOOL setLabelArg( const std::string& key, const LLStringExplicit& text ) override;
+ /*virtual*/ BOOL isCtrl() const override;
+ /*virtual*/ void onMouseEnter(S32 x, S32 y, MASK mask) override;
+ /*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask) override;
+ /*virtual*/ BOOL canFocusChildren() const override;
+ /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask) override;
+ /*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask) override;
+ /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask) override;
+ /*virtual*/ BOOL handleRightMouseUp(S32 x, S32 y, MASK mask) override;
+ /*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask) override;
// From LLFocusableElement
- /*virtual*/ void setFocus( BOOL b );
- /*virtual*/ BOOL hasFocus() const;
+ /*virtual*/ void setFocus( BOOL b ) override;
+ /*virtual*/ BOOL hasFocus() const override;
// New virtuals
@@ -207,11 +209,17 @@ public:
// Clear any user-provided input (text in a text editor, checked checkbox,
// selected radio button, etc.). Defaults to no-op.
virtual void clear();
+
virtual void setColor(const LLColor4& color);
virtual void setAlpha(F32 alpha);
virtual void setMinValue(LLSD min_value);
virtual void setMaxValue(LLSD max_value);
+ F32 getCurrentTransparency();
+
+ void setTransparencyType(ETypeTransparency type);
+ ETypeTransparency getTransparencyType() const {return mTransparencyType;}
+
BOOL focusNextItem(BOOL text_entry_only);
BOOL focusPrevItem(BOOL text_entry_only);
virtual // Singu Note: focusFirstItem is overridden for our old chat ui to prevent focusing on topmost uictrls.
@@ -248,8 +256,8 @@ public:
boost::signals2::connection setDoubleClickCallback( const mouse_signal_t::slot_type& cb );
// *TODO: Deprecate; for backwards compatability only:
- boost::signals2::connection setCommitCallback( boost::function cb, void* data);
- boost::signals2::connection setValidateBeforeCommit( boost::function cb );
+ boost::signals2::connection setCommitCallback( std::function cb, void* data);
+ boost::signals2::connection setValidateBeforeCommit( std::function cb );
static LLView* fromXML(LLXMLNodePtr node, LLView* parent, class LLUICtrlFactory* factory);
@@ -266,9 +274,13 @@ public:
template class CallbackRegistry : public LLRegistrySingleton
{};
- class CommitCallbackRegistry : public CallbackRegistry{};
+ class CommitCallbackRegistry : public CallbackRegistry
+ {
+ };
// the enable callback registry is also used for visiblity callbacks
- class EnableCallbackRegistry : public CallbackRegistry{};
+ class EnableCallbackRegistry : public CallbackRegistry
+ {
+ };
protected:
@@ -297,6 +309,10 @@ protected:
boost::signals2::connection mMakeVisibleControlConnection;
LLControlVariable* mMakeInvisibleControlVariable;
boost::signals2::connection mMakeInvisibleControlConnection;
+
+ static F32 sActiveControlTransparency;
+ static F32 sInactiveControlTransparency;
+
private:
BOOL mIsChrome;
@@ -304,6 +320,8 @@ private:
BOOL mTabStop;
BOOL mTentative;
+ ETypeTransparency mTransparencyType;
+
bool mCommitOnReturn;
class DefaultTabGroupFirstSorter;
diff --git a/indra/llui/lluictrlfactory.cpp b/indra/llui/lluictrlfactory.cpp
index 9209d484f..e41a8082a 100644
--- a/indra/llui/lluictrlfactory.cpp
+++ b/indra/llui/lluictrlfactory.cpp
@@ -412,13 +412,13 @@ LLMenuGL *LLUICtrlFactory::buildMenu(const std::string &filename, LLView* parent
}
// root must be called panel
- if( !root->hasName( "menu_bar" ) && !root->hasName( "menu" ))
+ if( !root->hasName( "menu_bar" ) && !root->hasName( "menu" ) && !root->hasName("context_menu"))
{
LL_WARNS() << "Root node should be named menu bar or menu in : " << filename << LL_ENDL;
return NULL;
}
- if (root->hasName("menu"))
+ if (root->hasName("menu") || root->hasName("context_menu"))
{
menu = (LLMenuGL*)LLMenuGL::fromXML(root, parentp, this);
}
@@ -496,7 +496,7 @@ void LLUICtrlFactory::rebuild()
panelp->setFocus(FALSE);
panelp->deleteAllChildren();
- buildPanel(panelp, filename.c_str(), &panelp->getFactoryMap());
+ buildPanel(panelp, filename, &panelp->getFactoryMap());
panelp->setVisible(visible);
}
diff --git a/indra/llui/llurlaction.cpp b/indra/llui/llurlaction.cpp
index fd9b3d9a6..74ce67e88 100644
--- a/indra/llui/llurlaction.cpp
+++ b/indra/llui/llurlaction.cpp
@@ -1,3 +1,5 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check it.
+// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
/**
* @file llurlaction.cpp
* @author Martin Reddy
@@ -24,7 +26,6 @@
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-
#include "linden_common.h"
#include "llurlaction.h"
@@ -32,6 +33,7 @@
#include "llwindow.h"
#include "llurlregistry.h"
+
// global state for the callback functions
LLUrlAction::url_callback_t LLUrlAction::sOpenURLCallback;
LLUrlAction::url_callback_t LLUrlAction::sOpenURLInternalCallback;
@@ -83,18 +85,19 @@ void LLUrlAction::openURLExternal(std::string url)
}
}
-void LLUrlAction::executeSLURL(std::string url)
+bool LLUrlAction::executeSLURL(std::string url, bool trusted_content)
{
if (sExecuteSLURLCallback)
{
- sExecuteSLURLCallback(url);
+ return sExecuteSLURLCallback(url, trusted_content);
}
+ return false;
}
-void LLUrlAction::clickAction(std::string url)
+void LLUrlAction::clickAction(std::string url, bool trusted_content)
{
// Try to handle as SLURL first, then http Url
- if ( (sExecuteSLURLCallback) && !sExecuteSLURLCallback(url) )
+ if ( (sExecuteSLURLCallback) && !sExecuteSLURLCallback(url, trusted_content) )
{
if (sOpenURLCallback)
{
@@ -157,3 +160,86 @@ void LLUrlAction::showProfile(std::string url)
}
}
}
+
+std::string LLUrlAction::getUserID(std::string url)
+{
+ LLURI uri(url);
+ LLSD path_array = uri.pathArray();
+ std::string id_str;
+ if (path_array.size() == 4)
+ {
+ id_str = path_array.get(2).asString();
+ }
+ return id_str;
+}
+
+std::string LLUrlAction::getObjectId(std::string url)
+{
+ LLURI uri(url);
+ LLSD path_array = uri.pathArray();
+ std::string id_str;
+ if (path_array.size() >= 3)
+ {
+ id_str = path_array.get(2).asString();
+ }
+ return id_str;
+}
+
+std::string LLUrlAction::getObjectName(std::string url)
+{
+ LLURI uri(url);
+ LLSD query_map = uri.queryMap();
+ std::string name;
+ if (query_map.has("name"))
+ {
+ name = query_map["name"].asString();
+ }
+ return name;
+}
+
+void LLUrlAction::sendIM(std::string url)
+{
+ std::string id_str = getUserID(url);
+ if (LLUUID::validate(id_str))
+ {
+ executeSLURL("secondlife:///app/agent/" + id_str + "/im");
+ }
+}
+
+void LLUrlAction::addFriend(std::string url)
+{
+ std::string id_str = getUserID(url);
+ if (LLUUID::validate(id_str))
+ {
+ executeSLURL("secondlife:///app/agent/" + id_str + "/requestfriend");
+ }
+}
+
+void LLUrlAction::removeFriend(std::string url)
+{
+ std::string id_str = getUserID(url);
+ if (LLUUID::validate(id_str))
+ {
+ executeSLURL("secondlife:///app/agent/" + id_str + "/removefriend");
+ }
+}
+
+void LLUrlAction::blockObject(std::string url)
+{
+ std::string object_id = getObjectId(url);
+ std::string object_name = getObjectName(url);
+ if (LLUUID::validate(object_id))
+ {
+ executeSLURL("secondlife:///app/agent/" + object_id + "/block/" + LLURI::escape(object_name));
+ }
+}
+
+void LLUrlAction::unblockObject(std::string url)
+{
+ std::string object_id = getObjectId(url);
+ std::string object_name = getObjectName(url);
+ if (LLUUID::validate(object_id))
+ {
+ executeSLURL("secondlife:///app/agent/" + object_id + "/unblock/" + object_name);
+ }
+}
diff --git a/indra/llui/llurlaction.h b/indra/llui/llurlaction.h
index 0747829b7..51ab8261b 100644
--- a/indra/llui/llurlaction.h
+++ b/indra/llui/llurlaction.h
@@ -28,11 +28,7 @@
#ifndef LL_LLURLACTION_H
#define LL_LLURLACTION_H
-#include
-#ifndef BOOST_FUNCTION_HPP_INCLUDED
-#include
-#define BOOST_FUNCTION_HPP_INCLUDED
-#endif
+#include
///
/// The LLUrlAction class provides a number of static functions that
@@ -60,7 +56,7 @@ public:
static void openURLExternal(std::string url);
/// execute the given secondlife: SLURL
- static void executeSLURL(std::string url);
+ static bool executeSLURL(std::string url, bool trusted_content = true);
/// if the Url specifies an SL location, teleport there
static void teleportToLocation(std::string url);
@@ -69,7 +65,7 @@ public:
static void showLocationOnMap(std::string url);
/// perform the appropriate action for left-clicking on a Url
- static void clickAction(std::string url);
+ static void clickAction(std::string url, bool trusted_content);
/// copy the label for a Url to the clipboard
static void copyLabelToClipboard(std::string url);
@@ -79,10 +75,18 @@ public:
/// if the Url specifies an SL command in the form like 'app/{cmd}/{id}/*', show its profile
static void showProfile(std::string url);
+ static std::string getUserID(std::string url);
+ static std::string getObjectName(std::string url);
+ static std::string getObjectId(std::string url);
+ static void sendIM(std::string url);
+ static void addFriend(std::string url);
+ static void removeFriend(std::string url);
+ static void blockObject(std::string url);
+ static void unblockObject(std::string url);
/// specify the callbacks to enable this class's functionality
- typedef boost::function url_callback_t;
- typedef boost::function execute_url_callback_t;
+ typedef std::function url_callback_t;
+ typedef std::function execute_url_callback_t;
static void setOpenURLCallback(url_callback_t cb);
static void setOpenURLInternalCallback(url_callback_t cb);
diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp
index 54dc1819c..8bf38caeb 100644
--- a/indra/llui/llurlentry.cpp
+++ b/indra/llui/llurlentry.cpp
@@ -1,3 +1,5 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check it.
+// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
/**
* @file llurlentry.cpp
* @author Martin Reddy
@@ -31,6 +33,7 @@
#include "lluri.h"
#include "llurlmatch.h"
#include "llurlregistry.h"
+#include "lluriparser.h"
#include "llavatarnamecache.h"
#include "llcachename.h"
@@ -38,14 +41,18 @@
//#include "lluicolortable.h"
#include "message.h"
-#define APP_HEADER_REGEX "((x-grid-location-info://[-\\w\\.]+/app)|(secondlife:///app))"
+#include //
+
+#define APP_HEADER_REGEX "((((x-grid-info://)|(x-grid-location-info://))[-\\w\\.]+(:\\d+)?/app)|(secondlife:///app))"
+#define X_GRID_OR_SECONDLIFE_HEADER_REGEX "((((x-grid-info://)|(x-grid-location-info://))[-\\w\\.]+(:\\d+)?/)|(secondlife://))"
// Utility functions
std::string localize_slapp_label(const std::string& url, const std::string& full_name);
LLUrlEntryBase::LLUrlEntryBase()
-{}
+{
+}
LLUrlEntryBase::~LLUrlEntryBase()
{
@@ -62,14 +69,13 @@ std::string LLUrlEntryBase::getIcon(const std::string &url)
return mIcon;
}
-/*LLStyle::Params LLUrlEntryBase::getStyle() const
+LLStyleSP LLUrlEntryBase::getStyle() const
{
- LLStyle::Params style_params;
- style_params.color = LLUIColorTable::instance().getColor("HTMLLinkColor");
- style_params.readonly_color = LLUIColorTable::instance().getColor("HTMLLinkColor");
- style_params.font.style = "UNDERLINE";
+ static LLUICachedControl color("HTMLLinkColor");
+ LLStyleSP style_params(new LLStyle(true, color, LLStringUtil::null));
+ //style_params->mUnderline = true; // Singu Note: We're not gonna bother here, underlining on hover
return style_params;
-}*/
+}
std::string LLUrlEntryBase::getIDStringFromUrl(const std::string &url) const
@@ -111,7 +117,7 @@ std::string LLUrlEntryBase::getLabelFromWikiLink(const std::string &url) const
{
// return the label part from [http://www.example.org Label]
const char *text = url.c_str();
- S32 start = 0;
+ size_t start = 0;
while (! isspace(text[start]))
{
start++;
@@ -127,7 +133,7 @@ std::string LLUrlEntryBase::getUrlFromWikiLink(const std::string &string) const
{
// return the url part from [http://www.example.org Label]
const char *text = string.c_str();
- S32 end = 0;
+ size_t end = 0;
while (! isspace(text[end]))
{
end++;
@@ -142,11 +148,14 @@ void LLUrlEntryBase::addObserver(const std::string &id,
// add a callback to be notified when we have a label for the uuid
LLUrlEntryObserver observer;
observer.url = url;
- observer.signal = new LLUrlLabelSignal();
- if (observer.signal)
+ try
{
+ observer.signal = new LLUrlLabelSignal();
observer.signal->connect(cb);
- mObservers.insert(std::pair(id, observer));
+ mObservers.emplace(id, observer);
+ }
+ catch (...)
+ {
}
}
@@ -178,12 +187,49 @@ bool LLUrlEntryBase::isLinkDisabled() const
return globally_disabled;
}
-static std::string getStringAfterToken(const std::string str, const std::string token)
+bool LLUrlEntryBase::isWikiLinkCorrect(const std::string& url)
+{
+ LLWString label = utf8str_to_wstring(getLabelFromWikiLink(url));
+ label.erase(std::remove(label.begin(), label.end(), L'\u200B'), label.end());
+ return (LLUrlRegistry::instance().hasUrl(wstring_to_utf8str(label))) ? false : true;
+}
+
+std::string LLUrlEntryBase::urlToLabelWithGreyQuery(const std::string &url) const
+{
+ LLUriParser up(unescapeUrl(url));
+ up.normalize();
+
+ std::string label;
+ up.extractParts();
+ up.glueFirst(label);
+
+ return label;
+}
+
+std::string LLUrlEntryBase::urlToGreyQuery(const std::string &url) const
+{
+ LLUriParser up(unescapeUrl(url));
+
+ std::string label;
+ up.extractParts();
+ up.glueFirst(label, false);
+
+ size_t pos = url.find(label);
+ if (pos == std::string::npos)
+ {
+ return "";
+ }
+ pos += label.size();
+ return url.substr(pos);
+}
+
+
+static std::string getStringAfterToken(const std::string& str, const std::string& token)
{
size_t pos = str.find(token);
if (pos == std::string::npos)
{
- return "";
+ return std::string();
}
pos += token.size();
@@ -194,8 +240,9 @@ static std::string getStringAfterToken(const std::string str, const std::string
// LLUrlEntryHTTP Describes generic http: and https: Urls
//
LLUrlEntryHTTP::LLUrlEntryHTTP()
+ : LLUrlEntryBase()
{
- mPattern = boost::regex("https?://([-\\w\\.]+)+(:\\d+)?(:\\w+)?(@\\d+)?(@\\w+)?/?\\S*",
+ mPattern = boost::regex("https?://([^\\s/?\\.#]+\\.?)+\\.\\w+(:\\d+)?(/\\S*)?",
boost::regex::perl|boost::regex::icase);
mMenuName = "menu_url_http.xml";
mTooltip = LLTrans::getString("TooltipHttpUrl");
@@ -206,6 +253,20 @@ std::string LLUrlEntryHTTP::getLabel(const std::string &url, const LLUrlLabelCal
return unescapeUrl(url);
}
+std::string LLUrlEntryHTTP::getUrl(const std::string &string) const
+{
+ if (string.find("://") == std::string::npos)
+ {
+ return "http://" + escapeUrl(string);
+ }
+ return escapeUrl(string);
+}
+
+std::string LLUrlEntryHTTP::getTooltip(const std::string &url) const
+{
+ return mTooltip;;
+}
+
//
// LLUrlEntryHTTP Describes generic http: and https: Urls with custom label
// We use the wikipedia syntax of [http://www.example.org Text]
@@ -238,20 +299,22 @@ std::string LLUrlEntryHTTPLabel::getUrl(const std::string &string) const
// LLUrlEntryHTTPNoProtocol Describes generic Urls like www.google.com
//
LLUrlEntryHTTPNoProtocol::LLUrlEntryHTTPNoProtocol()
+ : LLUrlEntryBase()
{
- mPattern = boost::regex("("
- "\\bwww\\.\\S+\\.\\S+" // i.e. www.FOO.BAR
- "|" // or
- "(?]+\\.(?:com|net|edu|org)([/:][^[:space:]<]*)?\\b" // i.e. FOO.net
- ")",
- boost::regex::perl|boost::regex::icase);
+ mPattern = boost::regex("\\bwww\\.\\S+\\.([^\\s<]*)?\\b", // i.e. www.FOO.BAR
+ boost::regex::perl | boost::regex::icase);
mMenuName = "menu_url_http.xml";
mTooltip = LLTrans::getString("TooltipHttpUrl");
}
std::string LLUrlEntryHTTPNoProtocol::getLabel(const std::string &url, const LLUrlLabelCallback &cb)
{
- return unescapeUrl(url);
+ return urlToLabelWithGreyQuery(url);
+}
+
+std::string LLUrlEntryHTTPNoProtocol::getQuery(const std::string &url) const
+{
+ return urlToGreyQuery(url);
}
std::string LLUrlEntryHTTPNoProtocol::getUrl(const std::string &string) const
@@ -263,6 +326,95 @@ std::string LLUrlEntryHTTPNoProtocol::getUrl(const std::string &string) const
return escapeUrl(string);
}
+std::string LLUrlEntryHTTPNoProtocol::getTooltip(const std::string &url) const
+{
+ return unescapeUrl(url);
+}
+
+LLUrlEntryInvalidSLURL::LLUrlEntryInvalidSLURL()
+ : LLUrlEntryBase()
+{
+ mPattern = boost::regex("(http://(maps.secondlife.com|slurl.com)/secondlife/|secondlife://(/app/(worldmap|teleport)/)?)[^ /]+(/-?[0-9]+){1,3}(/?(\\?title|\\?img|\\?msg)=\\S*)?/?",
+ boost::regex::perl|boost::regex::icase);
+ mMenuName = "menu_url_http.xml";
+ mTooltip = LLTrans::getString("TooltipHttpUrl");
+}
+
+std::string LLUrlEntryInvalidSLURL::getLabel(const std::string &url, const LLUrlLabelCallback &cb)
+{
+
+ return escapeUrl(url);
+}
+
+std::string LLUrlEntryInvalidSLURL::getUrl(const std::string &string) const
+{
+ return escapeUrl(string);
+}
+
+std::string LLUrlEntryInvalidSLURL::getTooltip(const std::string &url) const
+{
+ return unescapeUrl(url);
+}
+
+bool LLUrlEntryInvalidSLURL::isSLURLvalid(const std::string &url) const
+{
+ S32 actual_parts;
+
+ if(url.find(".com/secondlife/") != std::string::npos)
+ {
+ actual_parts = 5;
+ }
+ else if(url.find("/app/") != std::string::npos)
+ {
+ actual_parts = 6;
+ }
+ else
+ {
+ actual_parts = 3;
+ }
+
+ LLURI uri(url);
+ LLSD path_array = uri.pathArray();
+ S32 path_parts = path_array.size();
+ S32 x,y,z;
+
+ if (path_parts == actual_parts)
+ {
+ // handle slurl with (X,Y,Z) coordinates
+ LLStringUtil::convertToS32(path_array[path_parts-3],x);
+ LLStringUtil::convertToS32(path_array[path_parts-2],y);
+ LLStringUtil::convertToS32(path_array[path_parts-1],z);
+
+ if((x>= 0 && x<= 256) && (y>= 0 && y<= 256) && (z>= 0))
+ {
+ return TRUE;
+ }
+ }
+ else if (path_parts == (actual_parts-1))
+ {
+ // handle slurl with (X,Y) coordinates
+
+ LLStringUtil::convertToS32(path_array[path_parts-2],x);
+ LLStringUtil::convertToS32(path_array[path_parts-1],y);
+ ;
+ if((x>= 0 && x<= 256) && (y>= 0 && y<= 256))
+ {
+ return TRUE;
+ }
+ }
+ else if (path_parts == (actual_parts-2))
+ {
+ // handle slurl with (X) coordinate
+ LLStringUtil::convertToS32(path_array[path_parts-1],x);
+ if(x>= 0 && x<= 256)
+ {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
//
// LLUrlEntrySLURL Describes generic http: and https: Urls
//
@@ -284,6 +436,7 @@ std::string LLUrlEntrySLURL::getLabel(const std::string &url, const LLUrlLabelCa
// - http://slurl.com/secondlife/Place/X
// - http://slurl.com/secondlife/Place
//
+
LLURI uri(url);
LLSD path_array = uri.pathArray();
S32 path_parts = path_array.size();
@@ -335,13 +488,62 @@ std::string LLUrlEntrySLURL::getLocation(const std::string &url) const
return url.substr(pos, url.size() - pos);
}
+//
+// LLUrlEntrySeconlifeURL Describes *secondlife.com/ and *lindenlab.com/ urls to substitute icon 'hand.png' before link
+//
+LLUrlEntrySecondlifeURL::LLUrlEntrySecondlifeURL()
+{
+ mPattern = boost::regex("\\b(https?://)?([-\\w\\.]*\\.)?(secondlife|lindenlab)\\.com(:\\d{1,5})?(/\\S*)?",
+ boost::regex::perl|boost::regex::icase);
+
+ mIcon = "Hand";
+ mMenuName = "menu_url_http.xml";
+ mTooltip = LLTrans::getString("TooltipHttpUrl");
+}
+
+/// Return the url from a string that matched the regex
+std::string LLUrlEntrySecondlifeURL::getUrl(const std::string &string) const
+{
+ if (string.find("://") == std::string::npos)
+ {
+ return "https://" + escapeUrl(string);
+ }
+ return escapeUrl(string);
+}
+
+std::string LLUrlEntrySecondlifeURL::getLabel(const std::string &url, const LLUrlLabelCallback &cb)
+{
+ return urlToLabelWithGreyQuery(url);
+}
+
+std::string LLUrlEntrySecondlifeURL::getQuery(const std::string &url) const
+{
+ return urlToGreyQuery(url);
+}
+
+std::string LLUrlEntrySecondlifeURL::getTooltip(const std::string &url) const
+{
+ return url;
+}
+
+//
+// LLUrlEntrySimpleSecondlifeURL Describes *secondlife.com and *lindenlab.com urls to substitute icon 'hand.png' before link
+//
+LLUrlEntrySimpleSecondlifeURL::LLUrlEntrySimpleSecondlifeURL()
+ {
+ mPattern = boost::regex("(https?://)?([-\\w\\.]*\\.)?(secondlife|lindenlab)\\.com(?!\\S)",
+ boost::regex::perl|boost::regex::icase);
+
+ mIcon = "Hand";
+ mMenuName = "menu_url_http.xml";
+}
+
//
// LLUrlEntryAgent Describes a Second Life agent Url, e.g.,
// secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about
-// x-grid-location-info://lincoln.lindenlab.com/app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about
+// x-grid-info://lincoln.lindenlab.com/app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about
//
-LLUrlEntryAgent::LLUrlEntryAgent() :
- mAvatarNameCacheConnection()
+LLUrlEntryAgent::LLUrlEntryAgent()
{
mPattern = boost::regex(APP_HEADER_REGEX "/agent/[\\da-f-]+/\\w+",
boost::regex::perl|boost::regex::icase);
@@ -372,7 +574,15 @@ void LLUrlEntryAgent::callObservers(const std::string &id,
void LLUrlEntryAgent::onAvatarNameCache(const LLUUID& id,
const LLAvatarName& av_name)
{
- mAvatarNameCacheConnection.disconnect();
+ auto range = mAvatarNameCacheConnections.equal_range(id);
+ for (auto it = range.first; it != range.second; ++it)
+ {
+ if (it->second.connected())
+ {
+ it->second.disconnect();
+ }
+ }
+ mAvatarNameCacheConnections.erase(range.first, range.second);
std::string label = av_name.getCompleteName();
@@ -459,23 +669,19 @@ std::string LLUrlEntryAgent::getLabel(const std::string &url, const LLUrlLabelCa
}
else
{
- if (mAvatarNameCacheConnection.connected())
- {
- mAvatarNameCacheConnection.disconnect();
- }
- mAvatarNameCacheConnection = LLAvatarNameCache::get(agent_id, boost::bind(&LLUrlEntryAgent::onAvatarNameCache, this, _1, _2));
+ auto connection = LLAvatarNameCache::get(agent_id, boost::bind(&LLUrlEntryAgent::onAvatarNameCache, this, _1, _2));
+ mAvatarNameCacheConnections.emplace(agent_id, connection);
addObserver(agent_id_string, url, cb);
return LLTrans::getString("LoadingData");
}
}
-/*LLStyle::Params LLUrlEntryAgent::getStyle() const
+LLStyleSP LLUrlEntryAgent::getStyle() const
{
- LLStyle::Params style_params = LLUrlEntryBase::getStyle();
- style_params.color = LLUIColorTable::instance().getColor("HTMLLinkColor");
- style_params.readonly_color = LLUIColorTable::instance().getColor("HTMLLinkColor");
+ static LLUICachedControl color("HTMLAgentColor");
+ LLStyleSP style_params(new LLStyle(true, color, LLStringUtil::null));
return style_params;
-}*/
+}
std::string localize_slapp_label(const std::string& url, const std::string& full_name)
{
@@ -522,16 +728,25 @@ std::string LLUrlEntryAgent::getIcon(const std::string &url)
//
// LLUrlEntryAgentName describes a Second Life agent name Url, e.g.,
// secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/(completename|displayname|username)
-// x-grid-location-info://lincoln.lindenlab.com/app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/(completename|displayname|username)
+// x-grid-info://lincoln.lindenlab.com/app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/(completename|displayname|username)
//
-LLUrlEntryAgentName::LLUrlEntryAgentName() :
- mAvatarNameCacheConnection()
-{}
+LLUrlEntryAgentName::LLUrlEntryAgentName()
+{
+ mMenuName = "menu_url_agent.xml";
+}
void LLUrlEntryAgentName::onAvatarNameCache(const LLUUID& id,
const LLAvatarName& av_name)
{
- mAvatarNameCacheConnection.disconnect();
+ auto range = mAvatarNameCacheConnections.equal_range(id);
+ for (auto it = range.first; it != range.second; ++it)
+ {
+ if (it->second.connected())
+ {
+ it->second.disconnect();
+ }
+ }
+ mAvatarNameCacheConnections.erase(range.first, range.second);
std::string label = getName(av_name);
// received the agent name from the server - tell our observers
@@ -566,26 +781,24 @@ std::string LLUrlEntryAgentName::getLabel(const std::string &url, const LLUrlLab
}
else
{
- if (mAvatarNameCacheConnection.connected())
- {
- mAvatarNameCacheConnection.disconnect();
- }
- mAvatarNameCacheConnection = LLAvatarNameCache::get(agent_id, boost::bind(&LLUrlEntryAgentName::onAvatarNameCache, this, _1, _2));
+ auto connection = LLAvatarNameCache::get(agent_id, boost::bind(&LLUrlEntryAgentName::onAvatarNameCache, this, _1, _2));
+ mAvatarNameCacheConnections.emplace(agent_id, connection);
addObserver(agent_id_string, url, cb);
return LLTrans::getString("LoadingData");
}
}
-/*LLStyle::Params LLUrlEntryAgentName::getStyle() const
+LLStyleSP LLUrlEntryAgentName::getStyle() const
{
- // don't override default colors
- return LLStyle::Params().is_link(false);
-}*/
+ static LLUICachedControl color("HTMLAgentColor");
+ LLStyleSP style_params(new LLStyle(true, color, LLStringUtil::null));
+ return style_params;
+}
//
// LLUrlEntryAgentCompleteName describes a Second Life agent complete name Url, e.g.,
// secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/completename
-// x-grid-location-info://lincoln.lindenlab.com/app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/completename
+// x-grid-info://lincoln.lindenlab.com/app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/completename
//
LLUrlEntryAgentCompleteName::LLUrlEntryAgentCompleteName()
{
@@ -598,10 +811,26 @@ std::string LLUrlEntryAgentCompleteName::getName(const LLAvatarName& avatar_name
return avatar_name.getCompleteName();
}
+//
+// LLUrlEntryAgentLegacyName describes a Second Life agent legacy name Url, e.g.,
+// secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/legacyname
+// x-grid-info://lincoln.lindenlab.com/app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/legacyname
+//
+LLUrlEntryAgentLegacyName::LLUrlEntryAgentLegacyName()
+{
+ mPattern = boost::regex(APP_HEADER_REGEX "/agent/[\\da-f-]+/legacyname",
+ boost::regex::perl|boost::regex::icase);
+}
+
+std::string LLUrlEntryAgentLegacyName::getName(const LLAvatarName& avatar_name)
+{
+ return avatar_name.getLegacyName();
+}
+
//
// LLUrlEntryAgentDisplayName describes a Second Life agent display name Url, e.g.,
// secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/displayname
-// x-grid-location-info://lincoln.lindenlab.com/app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/displayname
+// x-grid-info://lincoln.lindenlab.com/app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/displayname
//
LLUrlEntryAgentDisplayName::LLUrlEntryAgentDisplayName()
{
@@ -617,7 +846,7 @@ std::string LLUrlEntryAgentDisplayName::getName(const LLAvatarName& avatar_name)
//
// LLUrlEntryAgentUserName describes a Second Life agent user name Url, e.g.,
// secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/username
-// x-grid-location-info://lincoln.lindenlab.com/app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/username
+// x-grid-info://lincoln.lindenlab.com/app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/username
//
LLUrlEntryAgentUserName::LLUrlEntryAgentUserName()
{
@@ -634,7 +863,7 @@ std::string LLUrlEntryAgentUserName::getName(const LLAvatarName& avatar_name)
// LLUrlEntryGroup Describes a Second Life group Url, e.g.,
// secondlife:///app/group/00005ff3-4044-c79f-9de8-fb28ae0df991/about
// secondlife:///app/group/00005ff3-4044-c79f-9de8-fb28ae0df991/inspect
-// x-grid-location-info://lincoln.lindenlab.com/app/group/00005ff3-4044-c79f-9de8-fb28ae0df991/inspect
+// x-grid-info://lincoln.lindenlab.com/app/group/00005ff3-4044-c79f-9de8-fb28ae0df991/inspect
//
LLUrlEntryGroup::LLUrlEntryGroup()
{
@@ -696,13 +925,12 @@ std::string LLUrlEntryGroup::getLabel(const std::string &url, const LLUrlLabelCa
}
}
-/*LLStyle::Params LLUrlEntryGroup::getStyle() const
+LLStyleSP LLUrlEntryGroup::getStyle() const
{
- LLStyle::Params style_params = LLUrlEntryBase::getStyle();
- style_params.color = LLUIColorTable::instance().getColor("HTMLLinkColor");
- style_params.readonly_color = LLUIColorTable::instance().getColor("HTMLLinkColor");
+ LLStyleSP style_params = LLUrlEntryBase::getStyle();
+ //style_params->mUnderline = false; // Singu Note: We're not gonna bother here, underlining on hover
return style_params;
-}*/
+}
//
@@ -714,7 +942,7 @@ LLUrlEntryInventory::LLUrlEntryInventory()
//*TODO: add supporting of inventory item names with whitespaces
//this pattern cann't parse for example
//secondlife:///app/inventory/0e346d8b-4433-4d66-a6b0-fd37083abc4c/select?name=name with spaces¶m2=value
- //x-grid-location-info://lincoln.lindenlab.com/app/inventory/0e346d8b-4433-4d66-a6b0-fd37083abc4c/select?name=name with spaces¶m2=value
+ //x-grid-info://lincoln.lindenlab.com/app/inventory/0e346d8b-4433-4d66-a6b0-fd37083abc4c/select?name=name with spaces¶m2=value
mPattern = boost::regex(APP_HEADER_REGEX "/inventory/[\\da-f-]+/\\w+\\S*",
boost::regex::perl|boost::regex::icase);
mMenuName = "menu_url_inventory.xml";
@@ -732,7 +960,7 @@ std::string LLUrlEntryInventory::getLabel(const std::string &url, const LLUrlLab
//
LLUrlEntryObjectIM::LLUrlEntryObjectIM()
{
- mPattern = boost::regex("secondlife:///app/objectim/[\\da-f-]+\?.*",
+ mPattern = boost::regex(APP_HEADER_REGEX "/objectim/[\\da-f-]+\?\\S*\\w",
boost::regex::perl|boost::regex::icase);
mMenuName = "menu_url_objectim.xml";
}
@@ -765,7 +993,7 @@ std::set LLUrlEntryParcel::sParcelInfoObservers;
///
/// LLUrlEntryParcel Describes a Second Life parcel Url, e.g.,
/// secondlife:///app/parcel/0000060e-4b39-e00b-d0c3-d98b1934e3a8/about
-/// x-grid-location-info://lincoln.lindenlab.com/app/parcel/0000060e-4b39-e00b-d0c3-d98b1934e3a8/about
+/// x-grid-info://lincoln.lindenlab.com/app/parcel/0000060e-4b39-e00b-d0c3-d98b1934e3a8/about
///
LLUrlEntryParcel::LLUrlEntryParcel()
{
@@ -860,7 +1088,7 @@ void LLUrlEntryParcel::processParcelInfo(const LLParcelData& parcel_data)
//
LLUrlEntryPlace::LLUrlEntryPlace()
{
- mPattern = boost::regex("((x-grid-location-info://[-\\w\\.]+/region/)|(secondlife://))\\S+/?(\\d+/\\d+/\\d+|\\d+/\\d+)/?",
+ mPattern = boost::regex("((((x-grid-info://)|(x-grid-location-info://))[-\\w\\.]+(:\\d+)?/region/)|(secondlife://))\\S+/?(\\d+/\\d+/\\d+|\\d+/\\d+)/?",
boost::regex::perl|boost::regex::icase);
mMenuName = "menu_url_slurl.xml";
mTooltip = LLTrans::getString("TooltipSLURL");
@@ -968,7 +1196,7 @@ std::string LLUrlEntryRegion::getLocation(const std::string &url) const
//
// LLUrlEntryTeleport Describes a Second Life teleport Url, e.g.,
// secondlife:///app/teleport/Ahern/50/50/50/
-// x-grid-location-info://lincoln.lindenlab.com/app/teleport/Ahern/50/50/50/
+// x-grid-info://lincoln.lindenlab.com/app/teleport/Ahern/50/50/50/
//
LLUrlEntryTeleport::LLUrlEntryTeleport()
{
@@ -1042,7 +1270,7 @@ std::string LLUrlEntryTeleport::getLocation(const std::string &url) const
//
LLUrlEntrySL::LLUrlEntrySL()
{
- mPattern = boost::regex("secondlife://(\\w+)?(:\\d+)?/\\S+",
+ mPattern = boost::regex(X_GRID_OR_SECONDLIFE_HEADER_REGEX "(\\w+)?(:\\d+)?/\\S+",
boost::regex::perl|boost::regex::icase);
mMenuName = "menu_url_slapp.xml";
mTooltip = LLTrans::getString("TooltipSLAPP");
@@ -1059,7 +1287,7 @@ std::string LLUrlEntrySL::getLabel(const std::string &url, const LLUrlLabelCallb
//
LLUrlEntrySLLabel::LLUrlEntrySLLabel()
{
- mPattern = boost::regex("\\[secondlife://\\S+[ \t]+[^\\]]+\\]",
+ mPattern = boost::regex("\\[" X_GRID_OR_SECONDLIFE_HEADER_REGEX "\\S+[ \t]+[^\\]]+\\]",
boost::regex::perl|boost::regex::icase);
mMenuName = "menu_url_slapp.xml";
mTooltip = LLTrans::getString("TooltipSLAPP");
@@ -1164,11 +1392,12 @@ std::string LLUrlEntryNoLink::getLabel(const std::string &url, const LLUrlLabelC
return getUrl(url);
}
-/*LLStyle::Params LLUrlEntryNoLink::getStyle() const
+LLStyleSP LLUrlEntryNoLink::getStyle() const
{
// Don't render as URL (i.e. no context menu or hand cursor).
- return LLStyle::Params().is_link(false);
-}*/
+ // Singu Note: What the heck? No, that's misleading!!
+ return LLUrlEntryBase::getStyle();
+}
//
@@ -1201,3 +1430,75 @@ std::string LLUrlEntryIcon::getIcon(const std::string &url)
LLStringUtil::trim(mIcon);
return mIcon;
}
+
+//
+// LLUrlEntryEmail Describes a generic mailto: Urls
+//
+LLUrlEntryEmail::LLUrlEntryEmail()
+ : LLUrlEntryBase()
+{
+ mPattern = boost::regex("(mailto:)?[\\w\\.\\-]+@[\\w\\.\\-]+\\.[a-z]{2,63}",
+ boost::regex::perl | boost::regex::icase);
+ mMenuName = "menu_url_email.xml";
+ mTooltip = LLTrans::getString("TooltipEmail");
+}
+
+std::string LLUrlEntryEmail::getLabel(const std::string &url, const LLUrlLabelCallback &cb)
+{
+ size_t pos = url.find("mailto:");
+
+ if (pos == std::string::npos)
+ {
+ return escapeUrl(url);
+ }
+
+ std::string ret = escapeUrl(url.substr(pos + 7, url.length() - pos + 8));
+ return ret;
+}
+
+std::string LLUrlEntryEmail::getUrl(const std::string &string) const
+{
+ if (string.find("mailto:") == std::string::npos)
+ {
+ return "mailto:" + escapeUrl(string);
+ }
+ return escapeUrl(string);
+}
+
+//
+//
+// LLUrlEntryJIRA describes a Jira Issue Tracker entry
+//
+LLUrlEntryJira::LLUrlEntryJira()
+{
+ mPattern = boost::regex("((?:ALCH|SV|BUG|CHOP|FIRE|MAINT|OPEN|SCR|STORM|SVC|VWR|WEB)-\\d+)",
+ boost::regex::perl);
+ mMenuName = "menu_url_http.xml";
+ mTooltip = LLTrans::getString("TooltipHttpUrl");
+}
+
+std::string LLUrlEntryJira::getLabel(const std::string &url, const LLUrlLabelCallback &cb)
+{
+ return unescapeUrl(url);
+}
+
+std::string LLUrlEntryJira::getTooltip(const std::string &string) const
+{
+ return getUrl(string);
+}
+
+std::string LLUrlEntryJira::getUrl(const std::string &url) const
+{
+ return (boost::format(
+ (url.find("ALCH") != std::string::npos) ?
+ "http://alchemy.atlassian.net/browse/%1%" :
+ (url.find("SV") != std::string::npos) ?
+ "https://singularityviewer.atlassian.net/browse/%1%" :
+ (url.find("FIRE") != std::string::npos) ?
+ "http://jira.phoenixviewer.com/browse/%1%" :
+ "http://jira.secondlife.com/browse/%1%"
+ ) % url).str();
+}
+//
+
+
diff --git a/indra/llui/llurlentry.h b/indra/llui/llurlentry.h
index e52fe8040..d526ea957 100644
--- a/indra/llui/llurlentry.h
+++ b/indra/llui/llurlentry.h
@@ -35,10 +35,7 @@
#include "llavatarname.h"
#include "llhost.h" // for resolving parcel name by parcel id
-#include
#include
-#include
-#include
class LLAvatarName;
@@ -78,11 +75,14 @@ public:
/// Given a matched Url, return a label for the Url
virtual std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb) { return url; }
+ /// Return port, query and fragment parts for the Url
+ virtual std::string getQuery(const std::string &url) const { return ""; }
+
/// Return an icon that can be displayed next to Urls of this type
virtual std::string getIcon(const std::string &url);
/// Return the style to render the displayed text
- //virtual LLStyle::Params getStyle() const;
+ virtual LLStyleSP getStyle() const;
/// Given a matched Url, return a tooltip string for the hyperlink
virtual std::string getTooltip(const std::string &string) const { return mTooltip; }
@@ -96,10 +96,16 @@ public:
/// Should this link text be underlined only when mouse is hovered over it?
virtual bool underlineOnHoverOnly(const std::string &string) const { return true; } //
+ virtual bool isTrusted() const { return false; }
+
virtual LLUUID getID(const std::string &string) const { return LLUUID::null; }
bool isLinkDisabled() const;
+ bool isWikiLinkCorrect(const std::string& url);
+
+ virtual bool isSLURLvalid(const std::string &url) const { return TRUE; };
+
protected:
std::string getIDStringFromUrl(const std::string &url) const;
std::string escapeUrl(const std::string &url) const;
@@ -107,6 +113,8 @@ protected:
std::string getLabelFromWikiLink(const std::string &url) const;
std::string getUrlFromWikiLink(const std::string &string) const;
void addObserver(const std::string &id, const std::string &url, const LLUrlLabelCallback &cb);
+ std::string urlToLabelWithGreyQuery(const std::string &url) const;
+ std::string urlToGreyQuery(const std::string &url) const;
virtual void callObservers(const std::string &id, const std::string &label, const std::string& icon);
typedef struct {
@@ -128,7 +136,9 @@ class LLUrlEntryHTTP : public LLUrlEntryBase
{
public:
LLUrlEntryHTTP();
- /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
+ /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb) override;
+ /*virtual*/ std::string getUrl(const std::string &string) const override;
+ /*virtual*/ std::string getTooltip(const std::string &url) const override;
};
///
@@ -138,9 +148,9 @@ class LLUrlEntryHTTPLabel : public LLUrlEntryBase
{
public:
LLUrlEntryHTTPLabel();
- /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
- /*virtual*/ std::string getTooltip(const std::string &string) const;
- /*virtual*/ std::string getUrl(const std::string &string) const;
+ /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb) override;
+ /*virtual*/ std::string getTooltip(const std::string &string) const override;
+ /*virtual*/ std::string getUrl(const std::string &string) const override;
};
///
@@ -150,8 +160,21 @@ class LLUrlEntryHTTPNoProtocol : public LLUrlEntryBase
{
public:
LLUrlEntryHTTPNoProtocol();
- /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
- /*virtual*/ std::string getUrl(const std::string &string) const;
+ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb) override;
+ std::string getQuery(const std::string &url) const override;
+ std::string getUrl(const std::string &string) const override;
+ std::string getTooltip(const std::string &url) const override;
+};
+
+class LLUrlEntryInvalidSLURL : public LLUrlEntryBase
+{
+public:
+ LLUrlEntryInvalidSLURL();
+ /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb) override;
+ /*virtual*/ std::string getUrl(const std::string &string) const override;
+ /*virtual*/ std::string getTooltip(const std::string &url) const override;
+
+ bool isSLURLvalid(const std::string &url) const override;
};
///
@@ -161,8 +184,31 @@ class LLUrlEntrySLURL : public LLUrlEntryBase
{
public:
LLUrlEntrySLURL();
- /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
- /*virtual*/ std::string getLocation(const std::string &url) const;
+ /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb) override;
+ /*virtual*/ std::string getLocation(const std::string &url) const override;
+};
+
+///
+/// LLUrlEntrySeconlifeURLs Describes *secondlife.com and *lindenlab.com Urls
+///
+class LLUrlEntrySecondlifeURL : public LLUrlEntryBase
+{
+public:
+ LLUrlEntrySecondlifeURL();
+ /*virtual*/ bool isTrusted() const override { return true; }
+ /*virtual*/ std::string getUrl(const std::string &string) const override;
+ /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb) override;
+ /*virtual*/ std::string getQuery(const std::string &url) const override;
+ /*virtual*/ std::string getTooltip(const std::string &url) const override;
+};
+
+///
+/// LLUrlEntrySeconlifeURLs Describes *secondlife.com and *lindenlab.com Urls
+///
+class LLUrlEntrySimpleSecondlifeURL : public LLUrlEntrySecondlifeURL
+{
+public:
+ LLUrlEntrySimpleSecondlifeURL();
};
///
@@ -174,22 +220,27 @@ public:
LLUrlEntryAgent();
~LLUrlEntryAgent()
{
- if (mAvatarNameCacheConnection.connected())
+ for(const auto& conn_pair : mAvatarNameCacheConnections)
{
- mAvatarNameCacheConnection.disconnect();
+ if (conn_pair.second.connected())
+ {
+ conn_pair.second.disconnect();
+ }
}
+ mAvatarNameCacheConnections.clear();
}
- /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
- /*virtual*/ std::string getIcon(const std::string &url);
- /*virtual*/ std::string getTooltip(const std::string &string) const;
- //*virtual*/ LLStyle::Params getStyle() const;
- /*virtual*/ LLUUID getID(const std::string &string) const;
- /*virtual*/ bool underlineOnHoverOnly(const std::string &string) const;
+ /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb) override;
+ /*virtual*/ std::string getIcon(const std::string &url) override;
+ /*virtual*/ std::string getTooltip(const std::string &string) const override;
+ /*virtual*/ LLStyleSP getStyle() const override;
+ /*virtual*/ LLUUID getID(const std::string &string) const override;
+ /*virtual*/ bool underlineOnHoverOnly(const std::string &string) const override;
protected:
- /*virtual*/ void callObservers(const std::string &id, const std::string &label, const std::string& icon);
+ /*virtual*/ void callObservers(const std::string &id, const std::string &label, const std::string& icon) override;
private:
void onAvatarNameCache(const LLUUID& id, const LLAvatarName& av_name);
- boost::signals2::connection mAvatarNameCacheConnection;
+ using avatar_name_cache_connection_map_t = std::multimap;
+ avatar_name_cache_connection_map_t mAvatarNameCacheConnections;
};
///
@@ -203,19 +254,25 @@ public:
LLUrlEntryAgentName();
~LLUrlEntryAgentName()
{
- if (mAvatarNameCacheConnection.connected())
+ for (const auto& conn_pair : mAvatarNameCacheConnections)
{
- mAvatarNameCacheConnection.disconnect();
+ if (conn_pair.second.connected())
+ {
+ conn_pair.second.disconnect();
+ }
}
+ mAvatarNameCacheConnections.clear();
+
}
- /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
- //*virtual*/ LLStyle::Params getStyle() const;
+ /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb) override;
+ /*virtual*/ LLStyleSP getStyle() const override;
protected:
// override this to pull out relevant name fields
virtual std::string getName(const LLAvatarName& avatar_name) = 0;
private:
void onAvatarNameCache(const LLUUID& id, const LLAvatarName& av_name);
- boost::signals2::connection mAvatarNameCacheConnection;
+ using avatar_name_cache_connection_map_t = std::multimap;
+ avatar_name_cache_connection_map_t mAvatarNameCacheConnections;
};
@@ -229,7 +286,15 @@ class LLUrlEntryAgentCompleteName : public LLUrlEntryAgentName
public:
LLUrlEntryAgentCompleteName();
private:
- /*virtual*/ std::string getName(const LLAvatarName& avatar_name);
+ /*virtual*/ std::string getName(const LLAvatarName& avatar_name) override;
+};
+
+class LLUrlEntryAgentLegacyName : public LLUrlEntryAgentName
+{
+public:
+ LLUrlEntryAgentLegacyName();
+private:
+ /*virtual*/ std::string getName(const LLAvatarName& avatar_name) override;
};
///
@@ -242,7 +307,7 @@ class LLUrlEntryAgentDisplayName : public LLUrlEntryAgentName
public:
LLUrlEntryAgentDisplayName();
private:
- /*virtual*/ std::string getName(const LLAvatarName& avatar_name);
+ /*virtual*/ std::string getName(const LLAvatarName& avatar_name) override;
};
///
@@ -255,7 +320,7 @@ class LLUrlEntryAgentUserName : public LLUrlEntryAgentName
public:
LLUrlEntryAgentUserName();
private:
- /*virtual*/ std::string getName(const LLAvatarName& avatar_name);
+ /*virtual*/ std::string getName(const LLAvatarName& avatar_name) override;
};
///
@@ -266,9 +331,9 @@ class LLUrlEntryGroup : public LLUrlEntryBase
{
public:
LLUrlEntryGroup();
- /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
- //*virtual*/ LLStyle::Params getStyle() const;
- /*virtual*/ LLUUID getID(const std::string &string) const;
+ /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb) override;
+ /*virtual*/ LLStyleSP getStyle() const override;
+ /*virtual*/ LLUUID getID(const std::string &string) const override;
private:
void onGroupNameReceived(const LLUUID& id, const std::string& name, bool is_group);
};
@@ -281,7 +346,7 @@ class LLUrlEntryInventory : public LLUrlEntryBase
{
public:
LLUrlEntryInventory();
- /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
+ /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb) override;
private:
};
@@ -293,8 +358,8 @@ class LLUrlEntryObjectIM : public LLUrlEntryBase
{
public:
LLUrlEntryObjectIM();
- /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
- /*virtual*/ std::string getLocation(const std::string &url) const;
+ /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb) override;
+ /*virtual*/ std::string getLocation(const std::string &url) const override;
private:
};
@@ -317,7 +382,7 @@ public:
LLUrlEntryParcel();
~LLUrlEntryParcel();
- /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
+ /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb) override;
// Sends a parcel info request to sim.
void sendParcelInfoRequest(const LLUUID& parcel_id);
@@ -353,8 +418,8 @@ class LLUrlEntryPlace : public LLUrlEntryBase
{
public:
LLUrlEntryPlace();
- /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
- /*virtual*/ std::string getLocation(const std::string &url) const;
+ /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb) override;
+ /*virtual*/ std::string getLocation(const std::string &url) const override;
};
///
@@ -365,8 +430,8 @@ class LLUrlEntryRegion : public LLUrlEntryBase
{
public:
LLUrlEntryRegion();
- /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
- /*virtual*/ std::string getLocation(const std::string &url) const;
+ /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb) override;
+ /*virtual*/ std::string getLocation(const std::string &url) const override;
};
///
@@ -377,8 +442,8 @@ class LLUrlEntryTeleport : public LLUrlEntryBase
{
public:
LLUrlEntryTeleport();
- /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
- /*virtual*/ std::string getLocation(const std::string &url) const;
+ /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb) override;
+ /*virtual*/ std::string getLocation(const std::string &url) const override;
};
///
@@ -389,7 +454,7 @@ class LLUrlEntrySL : public LLUrlEntryBase
{
public:
LLUrlEntrySL();
- /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
+ /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb) override;
};
///
@@ -400,10 +465,10 @@ class LLUrlEntrySLLabel : public LLUrlEntryBase
{
public:
LLUrlEntrySLLabel();
- /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
- /*virtual*/ std::string getUrl(const std::string &string) const;
- /*virtual*/ std::string getTooltip(const std::string &string) const;
- /*virtual*/ bool underlineOnHoverOnly(const std::string &string) const;
+ /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb) override;
+ /*virtual*/ std::string getUrl(const std::string &string) const override;
+ /*virtual*/ std::string getTooltip(const std::string &string) const override;
+ /*virtual*/ bool underlineOnHoverOnly(const std::string &string) const override;
};
///
@@ -414,8 +479,8 @@ class LLUrlEntryWorldMap : public LLUrlEntryBase
{
public:
LLUrlEntryWorldMap();
- /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
- /*virtual*/ std::string getLocation(const std::string &url) const;
+ /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb) override;
+ /*virtual*/ std::string getLocation(const std::string &url) const override;
};
///
@@ -425,9 +490,9 @@ class LLUrlEntryNoLink : public LLUrlEntryBase
{
public:
LLUrlEntryNoLink();
- /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
- /*virtual*/ std::string getUrl(const std::string &string) const;
- //*virtual*/ LLStyle::Params getStyle() const;
+ /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb) override;
+ /*virtual*/ std::string getUrl(const std::string &string) const override;
+ /*virtual*/ LLStyleSP getStyle() const override;
};
///
@@ -437,10 +502,35 @@ class LLUrlEntryIcon : public LLUrlEntryBase
{
public:
LLUrlEntryIcon();
- /*virtual*/ std::string getUrl(const std::string &string) const;
- /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
- /*virtual*/ std::string getIcon(const std::string &url);
+ /*virtual*/ std::string getUrl(const std::string &string) const override;
+ /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb) override;
+ /*virtual*/ std::string getIcon(const std::string &url) override;
};
+///
+/// LLUrlEntryEmail Describes a generic mailto: Urls
+///
+class LLUrlEntryEmail : public LLUrlEntryBase
+{
+public:
+ LLUrlEntryEmail();
+ /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb) override;
+ /*virtual*/ std::string getUrl(const std::string &string) const override;
+};
+
+//
+///
+/// LLUrlEntryJira describes a Jira Issue
+///
+class LLUrlEntryJira : public LLUrlEntryBase
+{
+public:
+ LLUrlEntryJira();
+ /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb) override;
+ /*virtual*/ std::string getTooltip(const std::string &string) const override;
+ /*virtual*/ std::string getUrl(const std::string &string) const override;
+
+};
+//
#endif
diff --git a/indra/llui/llurlmatch.cpp b/indra/llui/llurlmatch.cpp
index af4955ac4..717db6280 100644
--- a/indra/llui/llurlmatch.cpp
+++ b/indra/llui/llurlmatch.cpp
@@ -1,3 +1,5 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check it.
+// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
/**
* @file llurlmatch.cpp
* @author Martin Reddy
@@ -37,26 +39,29 @@ LLUrlMatch::LLUrlMatch() :
mIcon(""),
mMenuName(""),
mLocation(""),
- mUnderlineOnHoverOnly(false)
+ mUnderlineOnHoverOnly(false),
+ mTrusted(false)
{
}
-void LLUrlMatch::setValues(U32 start, U32 end, const std::string &url,
- const std::string &label, const std::string &tooltip,
- const std::string &icon, /*const LLStyle::Params& style,*/
+void LLUrlMatch::setValues(U32 start, U32 end, const std::string &url, const std::string &label,
+ const std::string& query, const std::string &tooltip,
+ const std::string &icon, const LLStyleSP& style,
const std::string &menu, const std::string &location,
- const LLUUID& id, bool underline_on_hover_only)
+ const LLUUID& id, bool underline_on_hover_only, bool trusted)
{
mStart = start;
mEnd = end;
mUrl = url;
mLabel = label;
+ mQuery = query;
mTooltip = tooltip;
mIcon = icon;
- //mStyle = style;
- //mStyle.link_href = url;
+ mStyle = style;
+ mStyle->setLinkHREF(url);
mMenuName = menu;
mLocation = location;
mID = id;
mUnderlineOnHoverOnly = underline_on_hover_only;
+ mTrusted = trusted;
}
diff --git a/indra/llui/llurlmatch.h b/indra/llui/llurlmatch.h
index af36e6925..fc0b505ec 100644
--- a/indra/llui/llurlmatch.h
+++ b/indra/llui/llurlmatch.h
@@ -30,8 +30,6 @@
//#include "linden_common.h"
-#include
-#include
#include "llstyle.h"
///
@@ -62,6 +60,9 @@ public:
/// return a label that can be used for the display of this Url
std::string getLabel() const { return mLabel; }
+ /// return a right part of url which should be drawn in grey
+ std::string getQuery() const { return mQuery; }
+
/// return a message that could be displayed in a tooltip or status bar
std::string getTooltip() const { return mTooltip; }
@@ -69,7 +70,7 @@ public:
std::string getIcon() const { return mIcon; }
/// Return the color to render the displayed text
- //LLStyle::Params getStyle() const { return mStyle; }
+ LLStyleSP getStyle() const { return mStyle; }
/// Return the name of a XUI file containing the context menu items
std::string getMenuName() const { return mMenuName; }
@@ -80,12 +81,15 @@ public:
/// Should this link text be underlined only when mouse is hovered over it?
bool underlineOnHoverOnly() const { return mUnderlineOnHoverOnly; }
+ /// Return true if Url is trusted.
+ bool isTrusted() const { return mTrusted; }
+
/// Change the contents of this match object (used by LLUrlRegistry)
void setValues(U32 start, U32 end, const std::string &url, const std::string &label,
- const std::string &tooltip, const std::string &icon,
- /*const LLStyle::Params& style, */const std::string &menu,
+ const std::string& query, const std::string &tooltip, const std::string &icon,
+ const LLStyleSP& style, const std::string &menu,
const std::string &location, const LLUUID& id,
- bool underline_on_hover_only = false );
+ bool underline_on_hover_only = false, bool trusted = false);
const LLUUID& getID() const { return mID; }
private:
@@ -93,13 +97,15 @@ private:
U32 mEnd;
std::string mUrl;
std::string mLabel;
+ std::string mQuery;
std::string mTooltip;
std::string mIcon;
std::string mMenuName;
std::string mLocation;
LLUUID mID;
- //LLStyle::Params mStyle;
+ LLStyleSP mStyle;
bool mUnderlineOnHoverOnly;
+ bool mTrusted;
};
#endif
diff --git a/indra/llui/llurlregistry.cpp b/indra/llui/llurlregistry.cpp
index 235b002d0..908531b0b 100644
--- a/indra/llui/llurlregistry.cpp
+++ b/indra/llui/llurlregistry.cpp
@@ -1,3 +1,5 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check it.
+// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
/**
* @file llurlregistry.cpp
* @author Martin Reddy
@@ -27,6 +29,7 @@
#include "linden_common.h"
#include "llurlregistry.h"
+#include "lluriparser.h"
#include
@@ -37,15 +40,26 @@ void LLUrlRegistryNullCallback(const std::string &url, const std::string &label,
LLUrlRegistry::LLUrlRegistry()
{
- mUrlEntry.reserve(20);
+ mUrlEntry.reserve(23); //
// Urls are matched in the order that they were registered
registerUrl(new LLUrlEntryNoLink());
- registerUrl(new LLUrlEntryIcon());
+ mUrlEntryIcon = new LLUrlEntryIcon();
+ registerUrl(mUrlEntryIcon);
+ mLLUrlEntryInvalidSLURL = new LLUrlEntryInvalidSLURL();
+ registerUrl(mLLUrlEntryInvalidSLURL);
registerUrl(new LLUrlEntrySLURL());
+
+ // decorated links for host names like: secondlife.com and lindenlab.com
+ mUrlEntryTrusted = new LLUrlEntrySecondlifeURL();
+ registerUrl(mUrlEntryTrusted);
+ registerUrl(new LLUrlEntrySimpleSecondlifeURL());
+
registerUrl(new LLUrlEntryHTTP());
- registerUrl(new LLUrlEntryHTTPLabel());
+ mUrlEntryHTTPLabel = new LLUrlEntryHTTPLabel();
+ registerUrl(mUrlEntryHTTPLabel);
registerUrl(new LLUrlEntryAgentCompleteName());
+ registerUrl(new LLUrlEntryAgentLegacyName());
registerUrl(new LLUrlEntryAgentDisplayName());
registerUrl(new LLUrlEntryAgentUserName());
// LLUrlEntryAgent*Name must appear before LLUrlEntryAgent since
@@ -59,14 +73,17 @@ LLUrlRegistry::LLUrlRegistry()
registerUrl(new LLUrlEntryObjectIM());
registerUrl(new LLUrlEntryPlace());
registerUrl(new LLUrlEntryInventory());
- registerUrl(new LLUrlEntryObjectIM());
//LLUrlEntrySL and LLUrlEntrySLLabel have more common pattern,
//so it should be registered in the end of list
registerUrl(new LLUrlEntrySL());
- registerUrl(new LLUrlEntrySLLabel());
- // most common pattern is a URL without any protocol,
- // e.g., "secondlife.com"
- registerUrl(new LLUrlEntryHTTPNoProtocol());
+ mUrlEntrySLLabel = new LLUrlEntrySLLabel();
+ registerUrl(mUrlEntrySLLabel);
+ registerUrl(new LLUrlEntryEmail());
+ // Parse teh jiras!
+ registerUrl(new LLUrlEntryJira()); //
+ // most common pattern is a URL without any protocol starting with "www",
+ // e.g., "www.secondlife.com"
+ registerUrl(new LLUrlEntryHTTPNoProtocol());
}
LLUrlRegistry::~LLUrlRegistry()
@@ -90,7 +107,7 @@ void LLUrlRegistry::registerUrl(LLUrlEntryBase *url, bool force_front)
}
}
-static bool matchRegex(const char *text, boost::regex regex, U32 &start, U32 &end)
+static bool matchRegex(const char *text, const boost::regex& regex, U32 &start, U32 &end)
{
boost::cmatch result;
bool found;
@@ -100,7 +117,7 @@ static bool matchRegex(const char *text, boost::regex regex, U32 &start, U32 &en
{
found = boost::regex_search(text, result, regex);
}
- catch (std::runtime_error &)
+ catch (const std::runtime_error &)
{
return false;
}
@@ -127,6 +144,11 @@ static bool matchRegex(const char *text, boost::regex regex, U32 &start, U32 &en
end--;
}
+ else if (text[end] == ']' && std::string(text+start, end-start).find('[') == std::string::npos)
+ {
+ end--;
+ }
+
return true;
}
@@ -142,32 +164,77 @@ static bool stringHasUrl(const std::string &text)
text.find(".edu") != std::string::npos ||
text.find(".org") != std::string::npos ||
text.find("") != std::string::npos ||
- text.find("
+static bool stringHasJira(const std::string &text)
+{
+ // fast heuristic test for a URL in a string. This is used
+ // to avoid lots of costly regex calls, BUT it needs to be
+ // kept in sync with the LLUrlEntry regexes we support.
+ return (text.find("ALCH") != std::string::npos ||
+ text.find("SV") != std::string::npos ||
+ text.find("BUG") != std::string::npos ||
+ text.find("CHOP") != std::string::npos ||
+ text.find("FIRE") != std::string::npos ||
+ text.find("MAINT") != std::string::npos ||
+ text.find("OPEN") != std::string::npos ||
+ text.find("SCR") != std::string::npos ||
+ text.find("STORM") != std::string::npos ||
+ text.find("SVC") != std::string::npos ||
+ text.find("VWR") != std::string::npos ||
+ text.find("WEB") != std::string::npos);
+}
+//
+
+bool LLUrlRegistry::findUrl(const std::string &text, LLUrlMatch &match, const LLUrlLabelCallback &cb, bool is_content_trusted)
{
// avoid costly regexes if there is clearly no URL in the text
- if (! stringHasUrl(text))
+ if (!(stringHasUrl(text) || stringHasJira(text))) //
{
return false;
}
// find the first matching regex from all url entries in the registry
U32 match_start = 0, match_end = 0;
- LLUrlEntryBase *match_entry = NULL;
+ LLUrlEntryBase *match_entry = nullptr;
std::vector::iterator it;
for (it = mUrlEntry.begin(); it != mUrlEntry.end(); ++it)
{
+ //Skip for url entry icon if content is not trusted
+ if(!is_content_trusted && (mUrlEntryIcon == *it))
+ {
+ continue;
+ }
+
LLUrlEntryBase *url_entry = *it;
U32 start = 0, end = 0;
if (matchRegex(text.c_str(), url_entry->getPattern(), start, end))
{
// does this match occur in the string before any other match
- if (start < match_start || match_entry == NULL)
+ if (start < match_start || match_entry == nullptr)
{
+
+ if (mLLUrlEntryInvalidSLURL == *it)
+ {
+ if(url_entry && url_entry->isSLURLvalid(text.substr(start, end - start + 1)))
+ {
+ continue;
+ }
+ }
+
+ if((mUrlEntryHTTPLabel == *it) || (mUrlEntrySLLabel == *it))
+ {
+ if(url_entry && !url_entry->isWikiLinkCorrect(text.substr(start, end - start + 1)))
+ {
+ continue;
+ }
+ }
+
match_start = start;
match_end = end;
match_entry = url_entry;
@@ -178,18 +245,32 @@ bool LLUrlRegistry::findUrl(const std::string &text, LLUrlMatch &match, const LL
// did we find a match? if so, return its details in the match object
if (match_entry)
{
+ // Skip if link is an email with an empty username (starting with @). See MAINT-5371.
+ if (match_start > 0 && text.substr(match_start - 1, 1) == "@")
+ return false;
+
// fill in the LLUrlMatch object and return it
std::string url = text.substr(match_start, match_end - match_start + 1);
+
+ if (match_entry == mUrlEntryTrusted)
+ {
+ LLUriParser up(url);
+ up.normalize();
+ url = up.normalizedUri();
+ }
+
match.setValues(match_start, match_end,
match_entry->getUrl(url),
match_entry->getLabel(url, cb),
+ match_entry->getQuery(url),
match_entry->getTooltip(url),
match_entry->getIcon(url),
- //match_entry->getStyle(),
+ match_entry->getStyle(),
match_entry->getMenuName(),
match_entry->getLocation(url),
match_entry->getID(url),
- match_entry->underlineOnHoverOnly(url));
+ match_entry->underlineOnHoverOnly(url),
+ match_entry->isTrusted());
return true;
}
@@ -209,7 +290,7 @@ bool LLUrlRegistry::findUrl(const LLWString &text, LLUrlMatch &match, const LLUr
// character encoding, so we need to update the start
// and end values to be correct for the wide string.
LLWString wurl = utf8str_to_wstring(match.getUrl());
- S32 start = text.find(wurl);
+ size_t start = text.find(wurl);
if (start == std::string::npos)
{
return false;
@@ -218,9 +299,10 @@ bool LLUrlRegistry::findUrl(const LLWString &text, LLUrlMatch &match, const LLUr
match.setValues(start, end, match.getUrl(),
match.getLabel(),
+ match.getQuery(),
match.getTooltip(),
match.getIcon(),
- //match.getStyle(),
+ match.getStyle(),
match.getMenuName(),
match.getLocation(),
match.getID(),
diff --git a/indra/llui/llurlregistry.h b/indra/llui/llurlregistry.h
index da16171a9..90099c6d1 100644
--- a/indra/llui/llurlregistry.h
+++ b/indra/llui/llurlregistry.h
@@ -33,9 +33,6 @@
#include "llsingleton.h"
#include "llstring.h"
-#include
-#include
-
/// This default callback for findUrl() simply ignores any label updates
void LLUrlRegistryNullCallback(const std::string &url,
const std::string &label,
@@ -73,7 +70,8 @@ public:
/// get the next Url in an input string, starting at a given character offset
/// your callback is invoked if the matched Url's label changes in the future
bool findUrl(const std::string &text, LLUrlMatch &match,
- const LLUrlLabelCallback &cb = &LLUrlRegistryNullCallback);
+ const LLUrlLabelCallback &cb = &LLUrlRegistryNullCallback,
+ bool is_content_trusted = false);
/// a slightly less efficient version of findUrl for wide strings
bool findUrl(const LLWString &text, LLUrlMatch &match,
@@ -92,6 +90,11 @@ private:
friend class LLSingleton;
std::vector mUrlEntry;
+ LLUrlEntryBase* mUrlEntryTrusted;
+ LLUrlEntryBase* mUrlEntryIcon;
+ LLUrlEntryBase* mLLUrlEntryInvalidSLURL;
+ LLUrlEntryBase* mUrlEntryHTTPLabel;
+ LLUrlEntryBase* mUrlEntrySLLabel;
};
#endif
diff --git a/indra/llvfs/lldir_linux.cpp b/indra/llvfs/lldir_linux.cpp
index 140532498..b98ff7768 100644
--- a/indra/llvfs/lldir_linux.cpp
+++ b/indra/llvfs/lldir_linux.cpp
@@ -102,7 +102,7 @@ LLDir_Linux::LLDir_Linux()
LL_INFOS() << "Running in dev checkout with mSkinBaseDir "
<< mSkinBaseDir << LL_ENDL;
else
- mSkinBaseDir = "";
+ mSkinBaseDir.clear();
}
if (mSkinBaseDir.empty())
{
diff --git a/indra/llvfs/lldir_win32.cpp b/indra/llvfs/lldir_win32.cpp
index 8547f1408..9f89641a3 100644
--- a/indra/llvfs/lldir_win32.cpp
+++ b/indra/llvfs/lldir_win32.cpp
@@ -140,7 +140,18 @@ LLDir_Win32::LLDir_Win32()
// LL_INFOS() << "mAppRODataDir = " << mAppRODataDir << LL_ENDL;
- mSkinBaseDir = mAppRODataDir + mDirDelimiter + "skins";
+ auto build_dir_pos = mExecutableDir.rfind("build-");
+ if (build_dir_pos != std::string::npos)
+ {
+ // ...we're in a dev checkout
+ mSkinBaseDir = mExecutableDir.substr(0, build_dir_pos) + "indra" + mDirDelimiter + "newview" + mDirDelimiter + "skins";
+ if (LLFile::isdir(mSkinBaseDir))
+ LL_INFOS() << "Running in dev checkout with mSkinBaseDir " << mSkinBaseDir << LL_ENDL;
+ else mSkinBaseDir.clear();
+ }
+
+ if (mSkinBaseDir.empty()) // ...normal installation running
+ mSkinBaseDir = mAppRODataDir + mDirDelimiter + "skins";
// Build the default cache directory
mDefaultCacheDir = buildSLOSCacheDir();
diff --git a/indra/llwindow/llwindow.cpp b/indra/llwindow/llwindow.cpp
index 762155d8f..f64b48667 100644
--- a/indra/llwindow/llwindow.cpp
+++ b/indra/llwindow/llwindow.cpp
@@ -49,8 +49,8 @@ LLSplashScreen *gSplashScreenp = NULL;
BOOL gDebugClicks = FALSE;
BOOL gDebugWindowProc = FALSE;
-const S32 gURLProtocolWhitelistCount = 4;
-const std::string gURLProtocolWhitelist[] = { "secondlife:", "http:", "https:", "data:"/*, "file:"*/ };
+const S32 gURLProtocolWhitelistCount = 5;
+const std::string gURLProtocolWhitelist[] = { "secondlife:", "http:", "https:", "data:", "mailto:" };
// CP: added a handler list - this is what's used to open the protocol and is based on registry entry
// only meaningful difference currently is that file: protocols are opened using http:
diff --git a/indra/llwindow/llwindow.h b/indra/llwindow/llwindow.h
index d0cb3802d..cf92c3a51 100644
--- a/indra/llwindow/llwindow.h
+++ b/indra/llwindow/llwindow.h
@@ -66,7 +66,7 @@ public:
};
public:
virtual void postInitialized() {}
- virtual void show() = 0;
+ virtual void show(bool focus = true) = 0;
virtual void hide() = 0;
virtual void close() = 0;
virtual BOOL getVisible() = 0;
diff --git a/indra/llwindow/llwindowheadless.h b/indra/llwindow/llwindowheadless.h
index 491f9afd2..ae3cd90f2 100644
--- a/indra/llwindow/llwindowheadless.h
+++ b/indra/llwindow/llwindowheadless.h
@@ -32,7 +32,7 @@
class LLWindowHeadless : public LLWindow
{
public:
- /*virtual*/ void show() {};
+ /*virtual*/ void show(bool) {};
/*virtual*/ void hide() {};
/*virtual*/ void close() {};
/*virtual*/ BOOL getVisible() {return FALSE;};
diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp
index 72c9f7628..8c11a05d3 100644
--- a/indra/llwindow/llwindowmacosx.cpp
+++ b/indra/llwindow/llwindowmacosx.cpp
@@ -80,7 +80,7 @@ BOOL check_for_card(const char* RENDERER, const char* bad_card)
"You can try to run Second Life, but it will probably crash or run\n"
"very slowly. Try anyway?",
bad_card);
- S32 button = OSMessageBox(buffer.c_str(), "Unsupported video card", OSMB_YESNO);
+ S32 button = OSMessageBox(buffer, "Unsupported video card", OSMB_YESNO);
if (OSBTN_YES == button)
{
return FALSE;
diff --git a/indra/llwindow/llwindowmesaheadless.h b/indra/llwindow/llwindowmesaheadless.h
index 6c0e872e2..e85c27f87 100644
--- a/indra/llwindow/llwindowmesaheadless.h
+++ b/indra/llwindow/llwindowmesaheadless.h
@@ -35,7 +35,7 @@
class LLWindowMesaHeadless : public LLWindow
{
public:
- /*virtual*/ void show() {};
+ /*virtual*/ void show(bool) {};
/*virtual*/ void hide() {};
/*virtual*/ void close() {};
/*virtual*/ BOOL getVisible() {return FALSE;};
diff --git a/indra/llwindow/llwindowsdl.cpp b/indra/llwindow/llwindowsdl.cpp
index 2ca113f55..3d6919393 100644
--- a/indra/llwindow/llwindowsdl.cpp
+++ b/indra/llwindow/llwindowsdl.cpp
@@ -790,7 +790,7 @@ LLWindowSDL::~LLWindowSDL()
}
-void LLWindowSDL::show()
+void LLWindowSDL::show(bool focus)
{
// *FIX: What to do with SDL?
}
diff --git a/indra/llwindow/llwindowsdl.h b/indra/llwindow/llwindowsdl.h
index a180be319..9a80856c5 100644
--- a/indra/llwindow/llwindowsdl.h
+++ b/indra/llwindow/llwindowsdl.h
@@ -49,7 +49,7 @@
class LLWindowSDL : public LLWindow
{
public:
- /*virtual*/ void show();
+ /*virtual*/ void show(bool focus);
/*virtual*/ void hide();
/*virtual*/ void close();
/*virtual*/ BOOL getVisible();
diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp
index c6cf352f6..e4ce7e837 100644
--- a/indra/llwindow/llwindowwin32.cpp
+++ b/indra/llwindow/llwindowwin32.cpp
@@ -717,9 +717,10 @@ void LLWindowWin32::postInitialized()
mCallbacks->handleDPIScaleChange(this, xDPIScale, yDPIScale);
}
-void LLWindowWin32::show()
+void LLWindowWin32::show(bool take_focus)
{
ShowWindow(mWindowHandle, SW_SHOW);
+ if (!take_focus) return;
SetForegroundWindow(mWindowHandle);
SetFocus(mWindowHandle);
}
diff --git a/indra/llwindow/llwindowwin32.h b/indra/llwindow/llwindowwin32.h
index 4f8693dbe..ca82f7512 100644
--- a/indra/llwindow/llwindowwin32.h
+++ b/indra/llwindow/llwindowwin32.h
@@ -41,7 +41,7 @@ class LLWindowWin32 : public LLWindow
{
public:
/*virtual*/ void postInitialized();
- /*virtual*/ void show();
+ /*virtual*/ void show(bool focus = true);
/*virtual*/ void hide();
/*virtual*/ void close();
/*virtual*/ BOOL getVisible();
diff --git a/indra/llxml/CMakeLists.txt b/indra/llxml/CMakeLists.txt
index d65bf3146..2245255cd 100644
--- a/indra/llxml/CMakeLists.txt
+++ b/indra/llxml/CMakeLists.txt
@@ -13,7 +13,7 @@ include_directories(
)
set(llxml_SOURCE_FILES
- #aixml.cpp
+ aixml.cpp
llcontrol.cpp
llxmlnode.cpp
llxmlparser.cpp
@@ -23,7 +23,7 @@ set(llxml_SOURCE_FILES
set(llxml_HEADER_FILES
CMakeLists.txt
- #aixml.h
+ aixml.h
llcontrol.h
llcontrolgroupreader.h
llxmlnode.h
diff --git a/indra/llxml/aixml.cpp b/indra/llxml/aixml.cpp
index dffe3d73a..02b972e80 100644
--- a/indra/llxml/aixml.cpp
+++ b/indra/llxml/aixml.cpp
@@ -32,7 +32,6 @@
#include "aixml.h"
#include "llmd5.h"
#include
-#include "aifile.h"
//=============================================================================
// Overview
@@ -311,11 +310,10 @@ void AIXMLElement::child(LLDate const& element)
//-----------------------------------------------------------------------------
// AIXMLStream
-AIXMLStream::AIXMLStream(LLFILE* fp, bool standalone) : mOfs(fp)
+AIXMLStream::AIXMLStream(const std::string& filename, bool standalone) : mOfs(filename)
{
- char const* sp = standalone ? " standalone=\"yes\"" : "";
- int rc = fprintf(fp, "\n", sp);
- if (rc < 0 || ferror(fp))
+ mOfs << "\n";
+ if (!mOfs)
{
// I don't think that errno is set to anything else but EBADF here,
// so there is not really any informative message to add here.
@@ -342,7 +340,6 @@ AIXMLParser::AIXMLParser(std::string const& filename, char const* file_desc, std
AIArgs args;
if (!mXmlTree.parseFile(filename, TRUE))
{
- AIFile dummy(filename, "rb"); // Check if the file can be opened at all (throws with a more descriptive error if not).
error = "AIXMLParser_Cannot_parse_FILEDESC_FILENAME";
}
else
diff --git a/indra/llxml/aixml.h b/indra/llxml/aixml.h
index 3ff971101..358eed756 100644
--- a/indra/llxml/aixml.h
+++ b/indra/llxml/aixml.h
@@ -151,7 +151,7 @@ void AIXMLElement::child(FWD_ITERATOR i1, FWD_ITERATOR const& i2)
class AIXMLStream {
protected:
llofstream mOfs;
- AIXMLStream(LLFILE* fp, bool standalone);
+ AIXMLStream(const std::string& filename, bool standalone);
~AIXMLStream();
};
@@ -159,7 +159,7 @@ class AIXMLStream {
class AIXMLRootElement : public AIXMLStream, public AIXMLElement
{
public:
- AIXMLRootElement(LLFILE* fp, char const* name, bool standalone = true) : AIXMLStream(fp, standalone), AIXMLElement(mOfs, name, 0) { }
+ AIXMLRootElement(const std::string& filename, char const* name, bool standalone = true) : AIXMLStream(filename, standalone), AIXMLElement(mOfs, name, 0) { }
};
class AIXMLElementParser
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index a15c9adc8..6f338aa4c 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -13,7 +13,7 @@ include(FMODSTUDIO)
include(GLOD)
include(FindOpenGL)
include(Hunspell)
-include(JsonCpp)
+include(Json)
include(LLAddBuildTest)
include(LLAppearance)
include(LLAudio)
@@ -43,6 +43,7 @@ include(UI)
include(ViewerMiscLibs)
include(WinManifest)
include(ZLIB)
+include(URIPARSER)
if (MSVC)
use_prebuilt_binary(vcredist)
@@ -52,7 +53,7 @@ include_directories(
${STATEMACHINE_INCLUDE_DIRS}
${DBUSGLIB_INCLUDE_DIRS}
${ZLIB_INCLUDE_DIRS}
- ${JSONCPP_INCLUDE_DIR}
+ ${JSON_INCLUDE_DIR}
${GLOD_INCLUDE_DIR}
${LLAUDIO_INCLUDE_DIRS}
${LLCHARACTER_INCLUDE_DIRS}
@@ -77,7 +78,7 @@ include_directories(
set(viewer_SOURCE_FILES
NACLantispam.cpp
aihttpview.cpp
- #aixmllindengenepool.cpp
+ aixmllindengenepool.cpp
alfloaterregiontracker.cpp
aoremotectrl.cpp
ascentfloatercontactgroups.cpp
@@ -174,6 +175,7 @@ set(viewer_SOURCE_FILES
llexternaleditor.cpp
llface.cpp
llfasttimerview.cpp
+ llfavoritesbar.cpp
llfeaturemanager.cpp
llfirstuse.cpp
llflexibleobject.cpp
@@ -231,6 +233,7 @@ set(viewer_SOURCE_FILES
llfloaterlandholdings.cpp
llfloaterlandmark.cpp
llfloatermap.cpp
+ llfloatermarketplacelistings.cpp
llfloatermediafilter.cpp
llfloatermediasettings.cpp
llfloatermemleak.cpp
@@ -243,7 +246,6 @@ set(viewer_SOURCE_FILES
llfloaterobjectiminfo.cpp
llfloaterobjectweights.cpp
llfloateropenobject.cpp
- llfloateroutbox.cpp
llfloaterparcel.cpp
llfloaterpathfindingcharacters.cpp
llfloaterpathfindinglinksets.cpp
@@ -320,6 +322,7 @@ set(viewer_SOURCE_FILES
llinventoryobserver.cpp
llinventorypanel.cpp
lljoystickbutton.cpp
+ lllandmarkactions.cpp
lllandmarklist.cpp
lllogchat.cpp
llloginhandler.cpp
@@ -387,7 +390,6 @@ set(viewer_SOURCE_FILES
llpanellandoptions.cpp
llpanellogin.cpp
llpanelmaininventory.cpp
- llpanelmarketplaceoutboxinventory.cpp
llpanelmediasettingsgeneral.cpp
llpanelmediasettingspermissions.cpp
llpanelmediasettingssecurity.cpp
@@ -613,7 +615,7 @@ set(viewer_HEADER_FILES
NACLantispam.h
aihttpview.h
- #aixmllindengenepool.h
+ aixmllindengenepool.h
alfloaterregiontracker.h
aoremotectrl.h
ascentfloatercontactgroups.h
@@ -710,6 +712,7 @@ set(viewer_HEADER_FILES
llexternaleditor.h
llface.h
llfasttimerview.h
+ llfavoritesbar.h
llfeaturemanager.h
llfirstuse.h
llflexibleobject.h
@@ -767,6 +770,7 @@ set(viewer_HEADER_FILES
llfloaterlandholdings.h
llfloaterlandmark.h
llfloatermap.h
+ llfloatermarketplacelistings.h
llfloatermediafilter.h
llfloatermediasettings.h
llfloatermemleak.h
@@ -779,7 +783,6 @@ set(viewer_HEADER_FILES
llfloaterobjectiminfo.h
llfloaterobjectweights.h
llfloateropenobject.h
- llfloateroutbox.h
llfloaterparcel.h
llfloaterpathfindingcharacters.h
llfloaterpathfindinglinksets.h
@@ -855,6 +858,7 @@ set(viewer_HEADER_FILES
llinventoryobserver.h
llinventorypanel.h
lljoystickbutton.h
+ lllandmarkactions.h
lllandmarklist.h
lllightconstants.h
lllogchat.h
@@ -924,7 +928,6 @@ set(viewer_HEADER_FILES
llpanellandoptions.h
llpanellogin.h
llpanelmaininventory.h
- llpanelmarketplaceoutboxinventory.h
llpanelmediasettingsgeneral.h
llpanelmediasettingspermissions.h
llpanelmediasettingssecurity.h
@@ -1642,6 +1645,7 @@ target_link_libraries(${VIEWER_BINARY_NAME}
${LLCOMMON_LIBRARIES}
${NDOF_LIBRARY}
${NVAPI_LIBRARY}
+ ${URIPARSER_LIBRARY}
${viewer_LIBRARIES}
${Boost_CONTEXT_LIBRARY}
${Boost_FILESYSTEM_LIBRARY}
@@ -1655,7 +1659,6 @@ target_link_libraries(${VIEWER_BINARY_NAME}
${GLOD_LIBRARIES}
${APRUTIL_LIBRARIES}
${OPENGL_LIBRARIES}
- ${JSONCPP_LIBRARIES}
${SDL_LIBRARY}
${SMARTHEAP_LIBRARY}
${UI_LIBRARIES}
diff --git a/indra/newview/aixmllindengenepool.cpp b/indra/newview/aixmllindengenepool.cpp
index 2e62a7955..c9d0b37aa 100644
--- a/indra/newview/aixmllindengenepool.cpp
+++ b/indra/newview/aixmllindengenepool.cpp
@@ -49,12 +49,11 @@
#include "llviewerprecompiledheaders.h"
#include "aixmllindengenepool.h"
#include "hippogridmanager.h"
+#include "llinventorymodel.h"
#include "llvisualparam.h"
#include "llviewerwearable.h"
#include "llquantize.h"
-extern void append_path_short(LLUUID const& id, std::string& path);
-
void AIXMLLindenGenepool::MetaData::toXML(std::ostream& os, int indentation) const
{
AIXMLElement tag(os, "meta", indentation);
@@ -68,7 +67,7 @@ AIXMLLindenGenepool::MetaData::MetaData(AIXMLElementParser const& parser)
parser.attribute(DEFAULT_LLDATE_NAME, mDate);
}
-AIXMLLindenGenepool::AIXMLLindenGenepool(LLFILE* fp) : AIXMLRootElement(fp, "linden_genepool")
+AIXMLLindenGenepool::AIXMLLindenGenepool(const std::string& filename) : AIXMLRootElement(filename, "linden_genepool")
{
attribute("version", "1.0");
attribute("metaversion", "1.0");
@@ -145,7 +144,20 @@ AIArchetype::MetaData::MetaData(AIXMLElementParser const& parser)
AIArchetype::MetaData::MetaData(LLViewerWearable const* wearable) : mName(wearable->getName()), mDescription(wearable->getDescription())
{
- append_path_short(wearable->getItemID(), mPath);
+ // Path should already end on '/' if it is not empty.
+ const LLUUID& root_id = gInventory.getRootFolderID();
+ LLUUID id = wearable->getItemID();
+ for(const LLInventoryObject* obj = gInventory.getObject(id); obj && id != root_id; obj = gInventory.getCategory(id))
+ {
+ std::string temp(mPath);
+ mPath = obj->getName();
+ if (!temp.empty())
+ {
+ mPath.append(1, '/');
+ mPath.append(temp);
+ }
+ id = obj->getParentUUID();
+ }
}
AIArchetype::AIArchetype(void) : mType(LLWearableType::WT_NONE)
diff --git a/indra/newview/aixmllindengenepool.h b/indra/newview/aixmllindengenepool.h
index c3a5a65d6..42aa5d35c 100644
--- a/indra/newview/aixmllindengenepool.h
+++ b/indra/newview/aixmllindengenepool.h
@@ -53,7 +53,7 @@ class AIXMLLindenGenepool : public AIXMLRootElement
MetaData(AIXMLElementParser const& parser);
};
- AIXMLLindenGenepool(LLFILE* fp);
+ AIXMLLindenGenepool(const std::string& filename);
};
class AIVisualParamIDValuePair
diff --git a/indra/newview/aoremotectrl.cpp b/indra/newview/aoremotectrl.cpp
index d9b782fca..5f57bcd20 100644
--- a/indra/newview/aoremotectrl.cpp
+++ b/indra/newview/aoremotectrl.cpp
@@ -33,7 +33,6 @@
#include "aoremotectrl.h"
#include "floaterao.h"
-#include "llbutton.h"
#include "lloverlaybar.h"
#include "lluictrlfactory.h"
#include "llviewercontrol.h"
@@ -46,80 +45,23 @@ AORemoteCtrl::AORemoteCtrl()
setFocusRoot(TRUE);
}
-AORemoteCtrl::~AORemoteCtrl()
-{
-}
-
-void AORemoteCtrl::draw()
-{
- LLButton* expand_button = getChild("popup_btn");
- if (expand_button)
- {
- if (expand_button->getToggleState())
- {
- expand_button->setImageOverlay("arrow_down.tga");
- }
- else
- {
- expand_button->setImageOverlay("arrow_up.tga");
- }
- }
-
- LLPanel::draw();
-}
-
void AORemoteCtrl::build()
{
- if (gSavedSettings.getBOOL("ShowAOSitPopup"))
- {
- LLUICtrlFactory::getInstance()->buildPanel(this, "panel_ao_remote_expanded.xml");
- }
- else
- {
- LLUICtrlFactory::getInstance()->buildPanel(this, "panel_ao_remote.xml");
- }
+ LLUICtrlFactory::getInstance()->buildPanel(this, gSavedSettings.getBOOL("ShowAOSitPopup") ? "panel_ao_remote_expanded.xml" : "panel_ao_remote.xml");
}
BOOL AORemoteCtrl::postBuild()
{
-
- childSetAction("ao_btn", onClickToggleAO, this);
- if (gSavedSettings.getBOOL("ShowAOSitPopup"))
- {
- childSetAction("ao_sit_btn", onClickToggleAOSit, this);
- //childSetAction("ao_show_btn", onClickShowAO, this);
- }
- childSetAction("popup_btn", onClickPopupBtn, this);
+ /*if (LLUICtrl* ctrl = findChild("ao_show_btn"))
+ ctrl->setCommitCallback(boost::bind(&LLFloaterAO::showInstance, LLSD()));*/
+ getChild("popup_btn")->setCommitCallback(boost::bind(&AORemoteCtrl::onClickPopupBtn, this));
return TRUE;
}
-// static
-void AORemoteCtrl::onClickToggleAO(void* data)
+void AORemoteCtrl::onClickPopupBtn()
{
- BOOL ao_enable = gSavedSettings.getBOOL("AOEnabled");
- gSavedSettings.setBOOL("AOEnabled", !ao_enable);
-}
-
-//static
-void AORemoteCtrl::onClickToggleAOSit(void* data)
-{
- BOOL sit_enable = gSavedSettings.getBOOL("AOSitsEnabled");
- gSavedSettings.setBOOL("AOSitsEnabled", !sit_enable);
-}
-
-//static
-void AORemoteCtrl::onClickShowAO(void* data)
-{
- LLFloaterAO::show(NULL);
-}
-
-//static
-void AORemoteCtrl::onClickPopupBtn(void* data)
-{
- AORemoteCtrl* remotep = (AORemoteCtrl*)data;
-
- remotep->deleteAllChildren();
- remotep->build();
+ deleteAllChildren();
+ build();
gOverlayBar->layoutButtons();
}
diff --git a/indra/newview/aoremotectrl.h b/indra/newview/aoremotectrl.h
index ca74e0de6..417f7b329 100644
--- a/indra/newview/aoremotectrl.h
+++ b/indra/newview/aoremotectrl.h
@@ -37,18 +37,12 @@ class AORemoteCtrl : public LLPanel
{
public:
AORemoteCtrl();
- virtual ~AORemoteCtrl();
- /*virtual*/ BOOL postBuild();
- /*virtual*/ void draw();
+ BOOL postBuild() override;
private:
void build();
-
- static void onClickToggleAO(void* data);
- static void onClickToggleAOSit(void* data);
- static void onClickShowAO(void* data);
- static void onClickPopupBtn(void* data);
+ void onClickPopupBtn();
};
#endif // AOREMOTECTRL_H
diff --git a/indra/newview/app_settings/ao_template.ini b/indra/newview/app_settings/ao_template.ini
index 03f02e305..ab4c68cac 100644
--- a/indra/newview/app_settings/ao_template.ini
+++ b/indra/newview/app_settings/ao_template.ini
@@ -63,6 +63,7 @@
[ Running ]
[ Turning Right ]
[ Turning Left ]
+[ Typing ]
[ Floating ]
[ Swimming Forward ]
[ Swimming Up ]
diff --git a/indra/newview/app_settings/ca-bundle.crt b/indra/newview/app_settings/ca-bundle.crt
index eff0eda08..e049f41fb 100644
--- a/indra/newview/app_settings/ca-bundle.crt
+++ b/indra/newview/app_settings/ca-bundle.crt
@@ -16,6 +16,301 @@
## Conversion done with mk-ca-bundle.pl version 1.27.
## SHA256: a3ac15b98179dd2f3c5de076d10b1d53048754372f7207c2f327510cdd78fbd8
##
+LetsEncrypt Root CA2
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 03:74:f1:c1:0b:b8:be:e9:c5:30:d3:e4:43:db:f8:ff:05:0d
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
+ Validity
+ Not Before: Mar 10 21:26:03 2019 GMT
+ Not After : Jun 8 21:26:03 2019 GMT
+ Subject: CN = login.virtual-nexus.xyz
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ RSA Public-Key: (4096 bit)
+ Modulus:
+ 00:aa:ea:b2:94:3e:9e:bf:08:c7:9a:3b:93:9d:4a:
+ a4:8e:18:f1:60:a1:26:d1:78:c1:72:11:8e:da:3e:
+ fa:16:3a:f4:a4:b2:de:ee:ec:eb:86:f1:88:2e:78:
+ 1a:04:90:44:e4:c2:72:c3:85:cf:8e:3b:9a:cd:f6:
+ 2c:4e:cb:39:06:18:2a:b9:70:dd:a5:d0:d6:71:01:
+ e8:e6:cc:f4:86:dd:88:2b:d5:de:28:a4:6c:a2:c9:
+ ab:dd:8b:0f:12:2a:1d:67:0f:fe:02:f9:33:1e:0c:
+ 84:be:16:d2:f2:b0:4d:b3:54:3d:db:df:83:8d:9a:
+ 1e:16:46:0b:f5:42:fb:91:4b:6a:95:7e:6b:48:e3:
+ 86:d8:60:5d:4d:9a:4e:a6:82:e7:05:02:83:78:72:
+ b4:62:8b:27:30:3a:20:8f:72:95:58:56:45:43:db:
+ 4e:e3:4a:87:0a:c9:58:f9:ec:63:65:d4:eb:f7:1d:
+ cc:2b:5c:8d:7d:61:54:0f:83:78:9a:b3:bf:db:87:
+ 45:b9:99:9b:54:75:e8:1c:52:29:f8:37:ad:24:5a:
+ ca:2b:1a:b2:11:8e:d4:34:bb:00:a8:e2:ae:ed:34:
+ 14:30:13:e1:06:c5:ee:d4:b2:9b:94:8d:f5:dc:2b:
+ a0:d3:ab:35:32:8b:e5:cf:d5:44:68:69:5d:3f:22:
+ 86:c9:2d:14:b6:b1:82:0c:fe:87:4d:a0:0a:76:1d:
+ c3:be:b9:ff:6e:c4:9e:f7:2d:d2:f5:ad:4d:aa:7f:
+ 4e:44:d6:7b:b4:6a:d0:71:52:48:2c:30:bf:11:b5:
+ df:70:40:30:cc:1a:e4:c0:a0:90:86:56:bf:36:92:
+ 2a:00:a5:0d:3b:2d:42:29:c1:4c:d6:9f:47:83:ff:
+ c1:c4:cc:04:08:9f:8b:2c:ca:4c:f5:d4:a5:38:81:
+ 6a:d0:4d:68:d9:fb:fa:1e:de:a1:c2:47:ea:d4:a8:
+ a3:b2:ba:47:50:b4:0e:15:a7:a7:ac:e2:a4:21:7c:
+ 20:c3:6b:ef:4f:3d:57:d0:91:ce:19:b2:da:4d:cd:
+ 7f:2d:2e:12:9d:e8:55:fc:02:ad:ea:57:68:d6:f9:
+ 96:9f:85:98:56:10:a2:bb:b6:7b:24:34:ab:9d:d7:
+ c9:56:47:40:b5:b1:22:80:b1:ae:37:73:6c:94:93:
+ 6c:db:97:47:b1:86:3c:87:5d:ad:52:2a:44:16:ce:
+ 0c:5c:94:1d:c2:cd:17:76:89:9a:ec:80:78:b9:a9:
+ c7:90:d2:c6:de:22:bb:95:1e:f6:ad:04:a0:46:c9:
+ 4b:12:2e:8d:ff:89:6c:c8:69:91:78:a0:f3:cf:f2:
+ 22:7d:68:4e:ee:32:0f:61:17:09:ba:94:bd:88:6d:
+ a8:65:cd
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Key Usage: critical
+ Digital Signature, Key Encipherment
+ X509v3 Extended Key Usage:
+ TLS Web Server Authentication, TLS Web Client Authentication
+ X509v3 Basic Constraints: critical
+ CA:FALSE
+ X509v3 Subject Key Identifier:
+ 2D:36:69:83:B8:E4:7D:38:D1:8F:8B:92:9E:A8:FD:6B:E9:25:29:97
+ X509v3 Authority Key Identifier:
+ keyid:A8:4A:6A:63:04:7D:DD:BA:E6:D1:39:B7:A6:45:65:EF:F3:A8:EC:A1
+
+ Authority Information Access:
+ OCSP - URI:http://ocsp.int-x3.letsencrypt.org
+ CA Issuers - URI:http://cert.int-x3.letsencrypt.org/
+
+ X509v3 Subject Alternative Name:
+ DNS:login.virtual-nexus.xyz
+ X509v3 Certificate Policies:
+ Policy: 2.23.140.1.2.1
+ Policy: 1.3.6.1.4.1.44947.1.1.1
+ CPS: http://cps.letsencrypt.org
+
+ CT Precertificate SCTs:
+ Signed Certificate Timestamp:
+ Version : v1 (0x0)
+ Log ID : 74:7E:DA:83:31:AD:33:10:91:21:9C:CE:25:4F:42:70:
+ C2:BF:FD:5E:42:20:08:C6:37:35:79:E6:10:7B:CC:56
+ Timestamp : Mar 10 22:26:03.415 2019 GMT
+ Extensions: none
+ Signature : ecdsa-with-SHA256
+ 30:45:02:21:00:98:49:3F:B0:C4:66:2D:CF:CE:91:36:
+ 15:AF:75:94:5B:FD:C2:CB:8F:F1:E2:8D:FA:C0:61:8E:
+ E6:F3:7B:A8:05:02:20:62:39:0F:66:B2:79:48:A8:49:
+ 41:2A:D4:59:86:C3:FA:AC:C1:5D:26:02:AC:E3:D8:C8:
+ 0F:40:34:64:F1:D1:36
+ Signed Certificate Timestamp:
+ Version : v1 (0x0)
+ Log ID : 29:3C:51:96:54:C8:39:65:BA:AA:50:FC:58:07:D4:B7:
+ 6F:BF:58:7A:29:72:DC:A4:C3:0C:F4:E5:45:47:F4:78
+ Timestamp : Mar 10 22:26:03.442 2019 GMT
+ Extensions: none
+ Signature : ecdsa-with-SHA256
+ 30:46:02:21:00:C7:09:49:5A:96:E5:B5:15:2A:F1:EA:
+ 03:A4:7D:10:89:23:9A:C2:C9:9F:35:85:AD:87:11:58:
+ A8:95:5C:0A:C6:02:21:00:88:14:C8:48:C7:6B:96:DB:
+ A2:AB:91:BD:F7:3D:AD:FA:37:F6:AD:BF:D7:24:DC:F0:
+ 11:CF:0C:D4:42:E0:72:A5
+ Signature Algorithm: sha256WithRSAEncryption
+ 42:55:9f:ea:ae:79:1d:9d:e9:06:23:a1:d0:a9:0f:d2:bc:08:
+ 92:b6:05:30:29:c2:00:fc:96:6e:b1:ff:9b:00:d7:c3:7b:34:
+ 47:02:81:2a:44:46:85:6c:7a:f5:c3:09:e2:9c:fd:1d:d3:2c:
+ a4:e9:a5:99:ec:47:bd:fe:39:d2:c9:d6:ac:dd:48:40:0b:9a:
+ 24:f1:0b:4e:02:62:aa:63:e4:dd:8f:ad:9a:6c:5a:0a:de:d0:
+ a2:67:b2:ea:fa:68:ff:18:ea:e1:73:35:89:45:dd:b7:ac:2d:
+ 58:8a:a3:6d:eb:41:f6:fa:60:8f:39:38:33:a0:d5:fd:56:5d:
+ 02:08:80:40:f6:f0:c1:68:e1:15:c8:fc:c3:64:a5:43:85:18:
+ ed:44:5d:f8:b9:20:43:9f:3d:8b:20:e0:55:cd:78:89:d4:db:
+ 80:23:88:0e:6f:f5:ef:66:52:a9:c6:b1:f1:5e:6c:d6:8e:18:
+ 7a:93:14:65:4b:1b:a7:55:7d:9d:a5:d2:15:a8:7d:a1:aa:dd:
+ ef:93:94:d5:3e:2f:ce:4b:bf:ac:e5:61:da:66:61:bd:42:08:
+ 53:58:73:a7:80:64:78:17:60:11:71:7f:75:17:bc:24:2f:57:
+ 8c:61:37:87:4e:0a:41:82:74:b0:69:14:5c:89:58:55:32:1f:
+ 06:1b:e2:24
+-----BEGIN CERTIFICATE-----
+MIIFjTCCA3WgAwIBAgIRANOxciY0IzLc9AUoUSrsnGowDQYJKoZIhvcNAQELBQAw
+TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
+cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTYxMDA2MTU0MzU1
+WhcNMjExMDA2MTU0MzU1WjBKMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNTGV0J3Mg
+RW5jcnlwdDEjMCEGA1UEAxMaTGV0J3MgRW5jcnlwdCBBdXRob3JpdHkgWDMwggEi
+MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCc0wzwWuUuR7dyXTeDs2hjMOrX
+NSYZJeG9vjXxcJIvt7hLQQWrqZ41CFjssSrEaIcLo+N15Obzp2JxunmBYB/XkZqf
+89B4Z3HIaQ6Vkc/+5pnpYDxIzH7KTXcSJJ1HG1rrueweNwAcnKx7pwXqzkrrvUHl
+Npi5y/1tPJZo3yMqQpAMhnRnyH+lmrhSYRQTP2XpgofL2/oOVvaGifOFP5eGr7Dc
+Gu9rDZUWfcQroGWymQQ2dYBrrErzG5BJeC+ilk8qICUpBMZ0wNAxzY8xOJUWuqgz
+uEPxsR/DMH+ieTETPS02+OP88jNquTkxxa/EjQ0dZBYzqvqEKbbUC8DYfcOTAgMB
+AAGjggFnMIIBYzAOBgNVHQ8BAf8EBAMCAYYwEgYDVR0TAQH/BAgwBgEB/wIBADBU
+BgNVHSAETTBLMAgGBmeBDAECATA/BgsrBgEEAYLfEwEBATAwMC4GCCsGAQUFBwIB
+FiJodHRwOi8vY3BzLnJvb3QteDEubGV0c2VuY3J5cHQub3JnMB0GA1UdDgQWBBSo
+SmpjBH3duubRObemRWXv86jsoTAzBgNVHR8ELDAqMCigJqAkhiJodHRwOi8vY3Js
+LnJvb3QteDEubGV0c2VuY3J5cHQub3JnMHIGCCsGAQUFBwEBBGYwZDAwBggrBgEF
+BQcwAYYkaHR0cDovL29jc3Aucm9vdC14MS5sZXRzZW5jcnlwdC5vcmcvMDAGCCsG
+AQUFBzAChiRodHRwOi8vY2VydC5yb290LXgxLmxldHNlbmNyeXB0Lm9yZy8wHwYD
+VR0jBBgwFoAUebRZ5nu25eQBc4AIiMgaWPbpm24wDQYJKoZIhvcNAQELBQADggIB
+ABnPdSA0LTqmRf/Q1eaM2jLonG4bQdEnqOJQ8nCqxOeTRrToEKtwT++36gTSlBGx
+A/5dut82jJQ2jxN8RI8L9QFXrWi4xXnA2EqA10yjHiR6H9cj6MFiOnb5In1eWsRM
+UM2v3e9tNsCAgBukPHAg1lQh07rvFKm/Bz9BCjaxorALINUfZ9DD64j2igLIxle2
+DPxW8dI/F2loHMjXZjqG8RkqZUdoxtID5+90FgsGIfkMpqgRS05f4zPbCEHqCXl1
+eO5HyELTgcVlLXXQDgAWnRzut1hFJeczY1tjQQno6f6s+nMydLN26WuU4s3UYvOu
+OsUxRlJu7TSRHqDC3lSE5XggVkzdaPkuKGQbGpny+01/47hfXXNB7HntWNZ6N2Vw
+p7G6OfY+YQrZwIaQmhrIqJZuigsrbe3W+gdn5ykE9+Ky0VgVUsfxo52mwFYs1JKY
+2PGDuWx8M6DlS6qQkvHaRUo0FMd8TsSlbF0/v965qGFKhSDeQoMpYnwcmQilRh/0
+ayLThlHLN81gSkJjVrPI0Y8xCVPB4twb1PFUd2fPM3sA1tJ83sZ5v8vgFv2yofKR
+PB0t6JzUA81mSqM3kxl5e+IZwhYAyO0OTg3/fs8HqGTNKd9BqoUwSRBzp06JMg5b
+rUCGwbCUDI0mxadJ3Bz4WxR6fyNpBK2yAinWEsikxqEt
+-----END CERTIFICATE-----
+
+LetsEncrypt Root CA
+
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ 03:74:f1:c1:0b:b8:be:e9:c5:30:d3:e4:43:db:f8:ff:05:0d
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
+ Validity
+ Not Before: Mar 10 21:26:03 2019 GMT
+ Not After : Jun 8 21:26:03 2019 GMT
+ Subject: CN = login.virtual-nexus.xyz
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ RSA Public-Key: (4096 bit)
+ Modulus:
+ 00:aa:ea:b2:94:3e:9e:bf:08:c7:9a:3b:93:9d:4a:
+ a4:8e:18:f1:60:a1:26:d1:78:c1:72:11:8e:da:3e:
+ fa:16:3a:f4:a4:b2:de:ee:ec:eb:86:f1:88:2e:78:
+ 1a:04:90:44:e4:c2:72:c3:85:cf:8e:3b:9a:cd:f6:
+ 2c:4e:cb:39:06:18:2a:b9:70:dd:a5:d0:d6:71:01:
+ e8:e6:cc:f4:86:dd:88:2b:d5:de:28:a4:6c:a2:c9:
+ ab:dd:8b:0f:12:2a:1d:67:0f:fe:02:f9:33:1e:0c:
+ 84:be:16:d2:f2:b0:4d:b3:54:3d:db:df:83:8d:9a:
+ 1e:16:46:0b:f5:42:fb:91:4b:6a:95:7e:6b:48:e3:
+ 86:d8:60:5d:4d:9a:4e:a6:82:e7:05:02:83:78:72:
+ b4:62:8b:27:30:3a:20:8f:72:95:58:56:45:43:db:
+ 4e:e3:4a:87:0a:c9:58:f9:ec:63:65:d4:eb:f7:1d:
+ cc:2b:5c:8d:7d:61:54:0f:83:78:9a:b3:bf:db:87:
+ 45:b9:99:9b:54:75:e8:1c:52:29:f8:37:ad:24:5a:
+ ca:2b:1a:b2:11:8e:d4:34:bb:00:a8:e2:ae:ed:34:
+ 14:30:13:e1:06:c5:ee:d4:b2:9b:94:8d:f5:dc:2b:
+ a0:d3:ab:35:32:8b:e5:cf:d5:44:68:69:5d:3f:22:
+ 86:c9:2d:14:b6:b1:82:0c:fe:87:4d:a0:0a:76:1d:
+ c3:be:b9:ff:6e:c4:9e:f7:2d:d2:f5:ad:4d:aa:7f:
+ 4e:44:d6:7b:b4:6a:d0:71:52:48:2c:30:bf:11:b5:
+ df:70:40:30:cc:1a:e4:c0:a0:90:86:56:bf:36:92:
+ 2a:00:a5:0d:3b:2d:42:29:c1:4c:d6:9f:47:83:ff:
+ c1:c4:cc:04:08:9f:8b:2c:ca:4c:f5:d4:a5:38:81:
+ 6a:d0:4d:68:d9:fb:fa:1e:de:a1:c2:47:ea:d4:a8:
+ a3:b2:ba:47:50:b4:0e:15:a7:a7:ac:e2:a4:21:7c:
+ 20:c3:6b:ef:4f:3d:57:d0:91:ce:19:b2:da:4d:cd:
+ 7f:2d:2e:12:9d:e8:55:fc:02:ad:ea:57:68:d6:f9:
+ 96:9f:85:98:56:10:a2:bb:b6:7b:24:34:ab:9d:d7:
+ c9:56:47:40:b5:b1:22:80:b1:ae:37:73:6c:94:93:
+ 6c:db:97:47:b1:86:3c:87:5d:ad:52:2a:44:16:ce:
+ 0c:5c:94:1d:c2:cd:17:76:89:9a:ec:80:78:b9:a9:
+ c7:90:d2:c6:de:22:bb:95:1e:f6:ad:04:a0:46:c9:
+ 4b:12:2e:8d:ff:89:6c:c8:69:91:78:a0:f3:cf:f2:
+ 22:7d:68:4e:ee:32:0f:61:17:09:ba:94:bd:88:6d:
+ a8:65:cd
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Key Usage: critical
+ Digital Signature, Key Encipherment
+ X509v3 Extended Key Usage:
+ TLS Web Server Authentication, TLS Web Client Authentication
+ X509v3 Basic Constraints: critical
+ CA:FALSE
+ X509v3 Subject Key Identifier:
+ 2D:36:69:83:B8:E4:7D:38:D1:8F:8B:92:9E:A8:FD:6B:E9:25:29:97
+ X509v3 Authority Key Identifier:
+ keyid:A8:4A:6A:63:04:7D:DD:BA:E6:D1:39:B7:A6:45:65:EF:F3:A8:EC:A1
+
+ Authority Information Access:
+ OCSP - URI:http://ocsp.int-x3.letsencrypt.org
+ CA Issuers - URI:http://cert.int-x3.letsencrypt.org/
+
+ X509v3 Subject Alternative Name:
+ DNS:login.virtual-nexus.xyz
+ X509v3 Certificate Policies:
+ Policy: 2.23.140.1.2.1
+ Policy: 1.3.6.1.4.1.44947.1.1.1
+ CPS: http://cps.letsencrypt.org
+
+ CT Precertificate SCTs:
+ Signed Certificate Timestamp:
+ Version : v1 (0x0)
+ Log ID : 74:7E:DA:83:31:AD:33:10:91:21:9C:CE:25:4F:42:70:
+ C2:BF:FD:5E:42:20:08:C6:37:35:79:E6:10:7B:CC:56
+ Timestamp : Mar 10 22:26:03.415 2019 GMT
+ Extensions: none
+ Signature : ecdsa-with-SHA256
+ 30:45:02:21:00:98:49:3F:B0:C4:66:2D:CF:CE:91:36:
+ 15:AF:75:94:5B:FD:C2:CB:8F:F1:E2:8D:FA:C0:61:8E:
+ E6:F3:7B:A8:05:02:20:62:39:0F:66:B2:79:48:A8:49:
+ 41:2A:D4:59:86:C3:FA:AC:C1:5D:26:02:AC:E3:D8:C8:
+ 0F:40:34:64:F1:D1:36
+ Signed Certificate Timestamp:
+ Version : v1 (0x0)
+ Log ID : 29:3C:51:96:54:C8:39:65:BA:AA:50:FC:58:07:D4:B7:
+ 6F:BF:58:7A:29:72:DC:A4:C3:0C:F4:E5:45:47:F4:78
+ Timestamp : Mar 10 22:26:03.442 2019 GMT
+ Extensions: none
+ Signature : ecdsa-with-SHA256
+ 30:46:02:21:00:C7:09:49:5A:96:E5:B5:15:2A:F1:EA:
+ 03:A4:7D:10:89:23:9A:C2:C9:9F:35:85:AD:87:11:58:
+ A8:95:5C:0A:C6:02:21:00:88:14:C8:48:C7:6B:96:DB:
+ A2:AB:91:BD:F7:3D:AD:FA:37:F6:AD:BF:D7:24:DC:F0:
+ 11:CF:0C:D4:42:E0:72:A5
+ Signature Algorithm: sha256WithRSAEncryption
+ 42:55:9f:ea:ae:79:1d:9d:e9:06:23:a1:d0:a9:0f:d2:bc:08:
+ 92:b6:05:30:29:c2:00:fc:96:6e:b1:ff:9b:00:d7:c3:7b:34:
+ 47:02:81:2a:44:46:85:6c:7a:f5:c3:09:e2:9c:fd:1d:d3:2c:
+ a4:e9:a5:99:ec:47:bd:fe:39:d2:c9:d6:ac:dd:48:40:0b:9a:
+ 24:f1:0b:4e:02:62:aa:63:e4:dd:8f:ad:9a:6c:5a:0a:de:d0:
+ a2:67:b2:ea:fa:68:ff:18:ea:e1:73:35:89:45:dd:b7:ac:2d:
+ 58:8a:a3:6d:eb:41:f6:fa:60:8f:39:38:33:a0:d5:fd:56:5d:
+ 02:08:80:40:f6:f0:c1:68:e1:15:c8:fc:c3:64:a5:43:85:18:
+ ed:44:5d:f8:b9:20:43:9f:3d:8b:20:e0:55:cd:78:89:d4:db:
+ 80:23:88:0e:6f:f5:ef:66:52:a9:c6:b1:f1:5e:6c:d6:8e:18:
+ 7a:93:14:65:4b:1b:a7:55:7d:9d:a5:d2:15:a8:7d:a1:aa:dd:
+ ef:93:94:d5:3e:2f:ce:4b:bf:ac:e5:61:da:66:61:bd:42:08:
+ 53:58:73:a7:80:64:78:17:60:11:71:7f:75:17:bc:24:2f:57:
+ 8c:61:37:87:4e:0a:41:82:74:b0:69:14:5c:89:58:55:32:1f:
+ 06:1b:e2:24
+-----BEGIN CERTIFICATE-----
+MIIEkjCCA3qgAwIBAgIQCgFBQgAAAVOFc2oLheynCDANBgkqhkiG9w0BAQsFADA/
+MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
+DkRTVCBSb290IENBIFgzMB4XDTE2MDMxNzE2NDA0NloXDTIxMDMxNzE2NDA0Nlow
+SjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUxldCdzIEVuY3J5cHQxIzAhBgNVBAMT
+GkxldCdzIEVuY3J5cHQgQXV0aG9yaXR5IFgzMIIBIjANBgkqhkiG9w0BAQEFAAOC
+AQ8AMIIBCgKCAQEAnNMM8FrlLke3cl03g7NoYzDq1zUmGSXhvb418XCSL7e4S0EF
+q6meNQhY7LEqxGiHC6PjdeTm86dicbp5gWAf15Gan/PQeGdxyGkOlZHP/uaZ6WA8
+SMx+yk13EiSdRxta67nsHjcAHJyse6cF6s5K671B5TaYucv9bTyWaN8jKkKQDIZ0
+Z8h/pZq4UmEUEz9l6YKHy9v6Dlb2honzhT+Xhq+w3Brvaw2VFn3EK6BlspkENnWA
+a6xK8xuQSXgvopZPKiAlKQTGdMDQMc2PMTiVFrqoM7hD8bEfwzB/onkxEz0tNvjj
+/PIzark5McWvxI0NHWQWM6r6hCm21AvA2H3DkwIDAQABo4IBfTCCAXkwEgYDVR0T
+AQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwfwYIKwYBBQUHAQEEczBxMDIG
+CCsGAQUFBzABhiZodHRwOi8vaXNyZy50cnVzdGlkLm9jc3AuaWRlbnRydXN0LmNv
+bTA7BggrBgEFBQcwAoYvaHR0cDovL2FwcHMuaWRlbnRydXN0LmNvbS9yb290cy9k
+c3Ryb290Y2F4My5wN2MwHwYDVR0jBBgwFoAUxKexpHsscfrb4UuQdf/EFWCFiRAw
+VAYDVR0gBE0wSzAIBgZngQwBAgEwPwYLKwYBBAGC3xMBAQEwMDAuBggrBgEFBQcC
+ARYiaHR0cDovL2Nwcy5yb290LXgxLmxldHNlbmNyeXB0Lm9yZzA8BgNVHR8ENTAz
+MDGgL6AthitodHRwOi8vY3JsLmlkZW50cnVzdC5jb20vRFNUUk9PVENBWDNDUkwu
+Y3JsMB0GA1UdDgQWBBSoSmpjBH3duubRObemRWXv86jsoTANBgkqhkiG9w0BAQsF
+AAOCAQEA3TPXEfNjWDjdGBX7CVW+dla5cEilaUcne8IkCJLxWh9KEik3JHRRHGJo
+uM2VcGfl96S8TihRzZvoroed6ti6WqEBmtzw3Wodatg+VyOeph4EYpr/1wXKtx8/
+wApIvJSwtmVi4MFU5aMqrSDE6ea73Mj2tcMyo5jMd6jmeWUHK8so/joWUoHOUgwu
+X4Po1QYz+3dszkDqMp4fklxBwXRsW10KXzPMTZ+sOPAveyxindmjkW8lGy+QsRlG
+PfZ+G6Z6h7mjem0Y+iWlkYcV4PIWL1iwBi8saCbGS5jN2p8M+X+Q7UNKEkROb3N6
+KOqkqm57TH2H3eDJAkSnh6/DNFu0Qg==
+-----END CERTIFICATE-----
+
+
GlobalSign Root CA
@@ -2943,106 +3238,6 @@ JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubSfZGL+T0yjWW06XyxV3bqxbYo
Ob8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ
-----END CERTIFICATE-----
-DST ACES CA X6
-# Issuer: CN=DST ACES CA X6,OU=DST ACES,O=Digital Signature Trust,C=US
-# Serial Number:0d:5e:99:0a:d6:9d:b7:78:ec:d8:07:56:3b:86:15:d9
-# Subject: CN=DST ACES CA X6,OU=DST ACES,O=Digital Signature Trust,C=US
-# Not Valid Before: Thu Nov 20 21:19:58 2003
-# Not Valid After : Mon Nov 20 21:19:58 2017
-# Fingerprint (MD5): 21:D8:4C:82:2B:99:09:33:A2:EB:14:24:8D:8E:5F:E8
-# Fingerprint (SHA1): 40:54:DA:6F:1C:3F:40:74:AC:ED:0F:EC:CD:DB:79:D1:53:FB:90:1D
-TRUSTED_DELEGATOR: SERVER_AUTH
-MUST_VERIFY_TRUST: EMAIL_PROTECTION, CODE_SIGNING
-=================================================
-MD5 Fingerprint=21:D8:4C:82:2B:99:09:33:A2:EB:14:24:8D:8E:5F:E8
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- 0d:5e:99:0a:d6:9d:b7:78:ec:d8:07:56:3b:86:15:d9
- Signature Algorithm: sha1WithRSAEncryption
- Issuer: C=US, O=Digital Signature Trust, OU=DST ACES, CN=DST ACES CA X6
- Validity
- Not Before: Nov 20 21:19:58 2003 GMT
- Not After : Nov 20 21:19:58 2017 GMT
- Subject: C=US, O=Digital Signature Trust, OU=DST ACES, CN=DST ACES CA X6
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:b9:3d:f5:2c:c9:94:dc:75:8a:95:5d:63:e8:84:
- 77:76:66:b9:59:91:5c:46:dd:92:3e:9f:f9:0e:03:
- b4:3d:61:92:bd:23:26:b5:63:ee:92:d2:9e:d6:3c:
- c8:0d:90:5f:64:81:b1:a8:08:0d:4c:d8:f9:d3:05:
- 28:52:b4:01:25:c5:95:1c:0c:7e:3e:10:84:75:cf:
- c1:19:91:63:cf:e8:a8:91:88:b9:43:52:bb:80:b1:
- 55:89:8b:31:fa:d0:b7:76:be:41:3d:30:9a:a4:22:
- 25:17:73:e8:1e:e2:d3:ac:2a:bd:5b:38:21:d5:2a:
- 4b:d7:55:7d:e3:3a:55:bd:d7:6d:6b:02:57:6b:e6:
- 47:7c:08:c8:82:ba:de:a7:87:3d:a1:6d:b8:30:56:
- c2:b3:02:81:5f:2d:f5:e2:9a:30:18:28:b8:66:d3:
- cb:01:96:6f:ea:8a:45:55:d6:e0:9d:ff:67:2b:17:
- 02:a6:4e:1a:6a:11:0b:7e:b7:7b:e7:98:d6:8c:76:
- 6f:c1:3b:db:50:93:7e:e5:d0:8e:1f:37:b8:bd:ba:
- c6:9f:6c:e9:7c:33:f2:32:3c:26:47:fa:27:24:02:
- c9:7e:1d:5b:88:42:13:6a:35:7c:7d:35:e9:2e:66:
- 91:72:93:d5:32:26:c4:74:f5:53:a3:b3:5d:9a:f6:
- 09:cb
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE
- X509v3 Key Usage: critical
- Digital Signature, Non Repudiation, Certificate Sign, CRL Sign
- X509v3 Subject Alternative Name:
- email:pki-ops@trustdst.com
- X509v3 Certificate Policies:
- Policy: 2.16.840.1.101.3.2.1.1.1
- CPS: http://www.trustdst.com/certificates/policy/ACES-index.html
-
- X509v3 Subject Key Identifier:
- 09:72:06:4E:18:43:0F:E5:D6:CC:C3:6A:8B:31:7B:78:8F:A8:83:B8
- Signature Algorithm: sha1WithRSAEncryption
- a3:d8:8e:d6:b2:db:ce:05:e7:32:cd:01:d3:04:03:e5:76:e4:
- 56:2b:9c:99:90:e8:08:30:6c:df:7d:3d:ee:e5:bf:b5:24:40:
- 84:49:e1:d1:28:ae:c4:c2:3a:53:30:88:f1:f5:77:6e:51:ca:
- fa:ff:99:af:24:5f:1b:a0:fd:f2:ac:84:ca:df:a9:f0:5f:04:
- 2e:ad:16:bf:21:97:10:81:3d:e3:ff:87:8d:32:dc:94:e5:47:
- 8a:5e:6a:13:c9:94:95:3d:d2:ee:c8:34:95:d0:80:d4:ad:32:
- 08:80:54:3c:e0:bd:52:53:d7:52:7c:b2:69:3f:7f:7a:cf:6a:
- 74:ca:fa:04:2a:9c:4c:5a:06:a5:e9:20:ad:45:66:0f:69:f1:
- dd:bf:e9:e3:32:8b:fa:e0:c1:86:4d:72:3c:2e:d8:93:78:0a:
- 2a:f8:d8:d2:27:3d:19:89:5f:5a:7b:8a:3b:cc:0c:da:51:ae:
- c7:0b:f7:2b:b0:37:05:ec:bc:57:23:e2:38:d2:9b:68:f3:56:
- 12:88:4f:42:7c:b8:31:c4:b5:db:e4:c8:21:34:e9:48:11:35:
- ee:fa:c7:92:57:c5:9f:34:e4:c7:f6:f7:0e:0b:4c:9c:68:78:
- 7b:71:31:c7:eb:1e:e0:67:41:f3:b7:a0:a7:cd:e5:7a:33:36:
- 6a:fa:9a:2b
------BEGIN CERTIFICATE-----
-MIIECTCCAvGgAwIBAgIQDV6ZCtadt3js2AdWO4YV2TANBgkqhkiG9w0BAQUFADBb
-MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3Qx
-ETAPBgNVBAsTCERTVCBBQ0VTMRcwFQYDVQQDEw5EU1QgQUNFUyBDQSBYNjAeFw0w
-MzExMjAyMTE5NThaFw0xNzExMjAyMTE5NThaMFsxCzAJBgNVBAYTAlVTMSAwHgYD
-VQQKExdEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdDERMA8GA1UECxMIRFNUIEFDRVMx
-FzAVBgNVBAMTDkRTVCBBQ0VTIENBIFg2MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
-MIIBCgKCAQEAuT31LMmU3HWKlV1j6IR3dma5WZFcRt2SPp/5DgO0PWGSvSMmtWPu
-ktKe1jzIDZBfZIGxqAgNTNj50wUoUrQBJcWVHAx+PhCEdc/BGZFjz+iokYi5Q1K7
-gLFViYsx+tC3dr5BPTCapCIlF3PoHuLTrCq9Wzgh1SpL11V94zpVvddtawJXa+ZH
-fAjIgrrep4c9oW24MFbCswKBXy314powGCi4ZtPLAZZv6opFVdbgnf9nKxcCpk4a
-ahELfrd755jWjHZvwTvbUJN+5dCOHze4vbrGn2zpfDPyMjwmR/onJALJfh1biEIT
-ajV8fTXpLmaRcpPVMibEdPVTo7NdmvYJywIDAQABo4HIMIHFMA8GA1UdEwEB/wQF
-MAMBAf8wDgYDVR0PAQH/BAQDAgHGMB8GA1UdEQQYMBaBFHBraS1vcHNAdHJ1c3Rk
-c3QuY29tMGIGA1UdIARbMFkwVwYKYIZIAWUDAgEBATBJMEcGCCsGAQUFBwIBFjto
-dHRwOi8vd3d3LnRydXN0ZHN0LmNvbS9jZXJ0aWZpY2F0ZXMvcG9saWN5L0FDRVMt
-aW5kZXguaHRtbDAdBgNVHQ4EFgQUCXIGThhDD+XWzMNqizF7eI+og7gwDQYJKoZI
-hvcNAQEFBQADggEBAKPYjtay284F5zLNAdMEA+V25FYrnJmQ6AgwbN99Pe7lv7Uk
-QIRJ4dEorsTCOlMwiPH1d25Ryvr/ma8kXxug/fKshMrfqfBfBC6tFr8hlxCBPeP/
-h40y3JTlR4peahPJlJU90u7INJXQgNStMgiAVDzgvVJT11J8smk/f3rPanTK+gQq
-nExaBqXpIK1FZg9p8d2/6eMyi/rgwYZNcjwu2JN4Cir42NInPRmJX1p7ijvMDNpR
-rscL9yuwNwXsvFcj4jjSm2jzVhKIT0J8uDHEtdvkyCE06UgRNe76x5JXxZ805Mf2
-9w4LTJxoeHtxMcfrHuBnQfO3oKfN5XozNmr6mis=
------END CERTIFICATE-----
-
SwissSign Gold CA - G2
# Issuer: CN=SwissSign Gold CA - G2,O=SwissSign AG,C=CH
# Serial Number:00:bb:40:1c:43:f5:5e:4f:b0
diff --git a/indra/newview/app_settings/cmd_line.xml b/indra/newview/app_settings/cmd_line.xml
index 253b0ad6e..fbb2bb10f 100644
--- a/indra/newview/app_settings/cmd_line.xml
+++ b/indra/newview/app_settings/cmd_line.xml
@@ -211,12 +211,6 @@
NoHardwareProbe
- noquicktime
-
- map-to
- NoQuickTime
-
-
nosound
map-to
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 79316b2f4..ad8787a7e 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -454,6 +454,8 @@
Boolean
Value
0
+ IsCOA
+ 1
AOAdvanced
@@ -476,6 +478,21 @@
Boolean
Value
1
+ IsCOA
+ 1
+
+ AOSwimEnabled
+
+ Comment
+ Overrides fly animations with swims when underwater.
+ Persist
+ 1
+ Type
+ Boolean
+ Value
+ 1
+ IsCOA
+ 1
AONoStandsInMouselook
@@ -827,7 +844,7 @@
Type
Boolean
Value
- 0
+ 1
LiruMiniBuildFloater
@@ -1159,17 +1176,6 @@ Found in Advanced->Rendering->Info Displays
Value
0
- FloaterUnfocusedBackgroundOpaque
-
- Comment
- Disables floaters going transparent when not in focus, may conflict with some skins, though.
- Persist
- 1
- Type
- Boolean
- Value
- 0
-
FSSynchronizeTextureMaps
Comment
@@ -1190,7 +1196,7 @@ Found in Advanced->Rendering->Info Displays
Type
Boolean
Value
- 0
+ 1
InstantMessageLogPathAnyAccount
@@ -1532,15 +1538,6 @@ This should be as low as possible, but too low may break functionality
Value
0
- InventorySortOrder
-
- Comment
- Specifies sort key for inventory items (+0 = name, +1 = date, +2 = folders always by name, +4 = system folders to top)
- Type
- U32
- Value
- 3
-
Blacklist.Settings
Comment
@@ -2560,6 +2557,17 @@ This should be as low as possible, but too low may break functionality
Value
300.0
+ ActiveFloaterTransparency
+
+ Comment
+ Transparency of active floaters (floaters that have focus)
+ Persist
+ 1
+ Type
+ F32
+ Value
+ 1
+
AdvanceSnapshot
Comment
@@ -5468,6 +5476,17 @@ This should be as low as possible, but too low may break functionality
Value
1
+ DebugHideEmptySystemFolders
+
+ Comment
+ Hide empty system folders when on
+ Persist
+ 1
+ Type
+ Boolean
+ Value
+ 1
+
DebugInventoryFilters
Comment
@@ -7683,6 +7702,17 @@ This should be as low as possible, but too low may break functionality
Value
24
+ RadarColumnNotesWidth
+
+ Comment
+ Width for radar's notes column
+ Persist
+ 1
+ Type
+ S32
+ Value
+ 24
+
RadarColumnAgeWidth
Comment
@@ -7771,6 +7801,17 @@ This should be as low as possible, but too low may break functionality
Value
0
+ RadarColumnNotesHidden
+
+ Comment
+ Hide radar's notes column
+ Persist
+ 1
+ Type
+ Boolean
+ Value
+ 1
+
RadarColumnAgeHidden
Comment
@@ -7839,6 +7880,28 @@ This should be as low as possible, but too low may break functionality
Value
1
+ RadarAlertFlood
+
+ Comment
+ Show the flood of people arriving and (if RadarAlertFloodLeaving) leaving when you login and when you open/close the Radar with RadarKeepOpen off.
+ Persist
+ 1
+ Type
+ Boolean
+ Value
+ 0
+
+ RadarAlertFloodLeaving
+
+ Comment
+ When activated along with RadarAlertFlood shows the flood of people leaving when you close the Radar with RadarKeepOpen off.
+ Persist
+ 1
+ Type
+ Boolean
+ Value
+ 0
+
RadarAlertShowDist
Comment
@@ -8109,10 +8172,26 @@ This should be as low as possible, but too low may break functionality
0
- FloaterOutboxRect
+ FloaterMarketplaceListingsRect
Comment
- Rectangle for merchant outbox window
+ Rectangle for Marketplace Listings window
+ Persist
+ 1
+ Type
+ Rect
+ Value
+
+ 0
+ 342
+ 310
+ 52
+
+
+ FloaterMarketplaceValidationRect
+
+ Comment
+ Rectangle for Marketplace Validation window
Persist
1
Type
@@ -9099,6 +9178,22 @@ This should be as low as possible, but too low may break functionality
Value
400
+ HTMLAgentColor
+
+ Comment
+ Color of hyperlinked user/object names
+ Persist
+ 1
+ Type
+ Color4
+ Value
+
+ 0.600000023842
+ 0.600000023842
+ 1.0
+ 1.0
+
+
HTMLLinkColor
Comment
@@ -9339,6 +9434,17 @@ This should be as low as possible, but too low may break functionality
Value
1
+ InactiveFloaterTransparency
+
+ Comment
+ Transparency of inactive floaters (floaters that have no focus)
+ Persist
+ 1
+ Type
+ F32
+ Value
+ 1
+
InBandwidth
Comment
@@ -9416,12 +9522,12 @@ This should be as low as possible, but too low may break functionality
Value
0
- InventoryDisplayOutbox
+ InventoryOutboxDisplayBoth
Comment
- Override merchant inventory outbox display
+ Show the legacy Merchant Outbox UI as well as the Marketplace Listings UI
Persist
- 0
+ 1
Type
Boolean
Value
@@ -9438,6 +9544,17 @@ This should be as low as possible, but too low may break functionality
Value
0
+ InventoryOutboxMakeVisible
+
+ Comment
+ Enable making the Merchant Outbox and Inbox visible in the inventory for debug purposes.
+ Persist
+ 1
+ Type
+ Boolean
+ Value
+ 1
+
InventoryOutboxMaxFolderCount
Comment
@@ -9447,7 +9564,7 @@ This should be as low as possible, but too low may break functionality
Type
U32
Value
- 21
+ 20
InventoryOutboxMaxFolderDepth
@@ -9471,6 +9588,17 @@ This should be as low as possible, but too low may break functionality
Value
200
+ InventoryOutboxMaxStockItemCount
+
+ Comment
+ Maximum number of items allowed in a stock folder.
+ Persist
+ 0
+ Type
+ U32
+ Value
+ 200
+
InventorySortOrder
Comment
@@ -9482,6 +9610,17 @@ This should be as low as possible, but too low may break functionality
Value
7
+ MarketplaceListingsSortOrder
+
+ Comment
+ Specifies sort for marketplace listings
+ Persist
+ 1
+ Type
+ U32
+ Value
+ 2
+
InvertMouse
Comment
@@ -10323,6 +10462,17 @@ This should be as low as possible, but too low may break functionality
Value
+ MarketplaceListingsLogging
+
+ Comment
+ Enable debug output associated with the Marketplace Listings (SLM) API.
+ Persist
+ 1
+ Type
+ Boolean
+ Value
+ 0
+
MaxDragDistance
Comment
@@ -13838,7 +13988,7 @@ This should be as low as possible, but too low may break functionality
Type
Boolean
Value
- 1
+ 0
RenderHideGroupTitle
diff --git a/indra/newview/app_settings/settings_ascent.xml b/indra/newview/app_settings/settings_ascent.xml
index dd373885d..a11c8a970 100644
--- a/indra/newview/app_settings/settings_ascent.xml
+++ b/indra/newview/app_settings/settings_ascent.xml
@@ -818,6 +818,17 @@
Value
/regionsay
+ SinguCmdLineSetting
+
+ Comment
+ Set or toggle debug settings from the chatbar.
+ Persist
+ 1
+ Type
+ String
+ Value
+ /setdebug
+
SinguCmdLineURL
Comment
@@ -862,17 +873,6 @@
Value
0
- SinguMotionResetsCamera
-
- Comment
- Allow camera to reset when moving.
- Persist
- 1
- Type
- Boolean
- Value
- 1
-
SinguLastKnownReleaseBuild
Comment
@@ -895,6 +895,54 @@
Value
0
+ SinguMotionResetsCamera
+
+ Comment
+ Allow camera to reset when moving.
+ Persist
+ 1
+ Type
+ Boolean
+ Value
+ 1
+
+ SinguMotionResetsCameraReset
+
+ Comment
+ Disable for the behavior Liru intended SinguMotionResetsCamera to have, wherein it doesn't reset every time you press escape, teleport, or whatever else! So you can walk around and your camera won't reset at all like it was meant to be.
+RIP Latif Khalifa.
+ Persist
+ 1
+ Type
+ Boolean
+ Value
+ 1
+
+ SinguPostProcessDefault
+
+ Comment
+ Default post process preset, changing this will change your active preset
+ Persist
+ 1
+ Type
+ String
+ Value
+ Default
+
+ SinguReplaceLinks
+
+ Comment
+ Whether or not to visually replace special links like SLURLs with labels where applicable.
+While having this on allows people to mislead you with links that look like other links, it also allows you to use SLURLs that appear as people's names and increasingly more scripts use this to run faster.
+You can always select the text, right click and select Copy Raw to copy the hidden contents of the link.
+Changing this setting only affects new text.
+ Persist
+ 1
+ Type
+ Boolean
+ Value
+ 1
+
WarnRecommendedUpdate
Comment
@@ -1006,6 +1054,28 @@
Value
3.5
+ EmergencyTeleportSeconds
+
+ Comment
+ The remaining time left in seconds when to execute an emergency teleport out of a restarting region.
+ Persist
+ 1
+ Type
+ U32
+ Value
+ 20
+
+ LiruEnableWIPUI
+
+ Comment
+ Whether or not to enable UI components that probably don't work yet.
+ Persist
+ 1
+ Type
+ Boolean
+ Value
+ 0
+
LiruFlashWhenMinimized
Comment
@@ -1713,6 +1783,17 @@
IsCOA
1
+ ToolbarVisibleMarketplaceListings
+
+ Comment
+ Whether or not the button for marketplace listings is on the toolbar
+ Persist
+ 1
+ Type
+ Boolean
+ Value
+ 0
+
ToolbarVisibleMeanEvents
Comment
@@ -1843,10 +1924,10 @@
IsCOA
1
- ToolbarVisibleOutbox
+ ToolbarVisibleMarketplaceListings
Comment
- Whether or not the button for outbox is on the toolbar
+ Whether or not the button for Marketplace Listings is on the toolbar
Persist
1
Type
@@ -1869,19 +1950,6 @@
IsCOA
1
- ToolbarVisibleOutbox
-
- Comment
- Whether or not the button for the merchant outbox is on the toolbar
- Persist
- 1
- Type
- Boolean
- Value
- 0
- IsCOA
- 1
-
ToolbarVisibleOutfit
Comment
diff --git a/indra/newview/app_settings/settings_per_account.xml b/indra/newview/app_settings/settings_per_account.xml
index 2dd4904f4..27a01079c 100644
--- a/indra/newview/app_settings/settings_per_account.xml
+++ b/indra/newview/app_settings/settings_per_account.xml
@@ -186,6 +186,61 @@
Value
+ AODefaultTyping
+
+ Comment
+ Default typing anim
+ Persist
+ 1
+ Type
+ String
+ Value
+
+
+ AODefaultFloat
+
+ Comment
+ Default float anim
+ Persist
+ 1
+ Type
+ String
+ Value
+
+
+ AODefaultSwim
+
+ Comment
+ Default swim anim
+ Persist
+ 1
+ Type
+ String
+ Value
+
+
+ AODefaultSwimUp
+
+ Comment
+ Default swimup anim
+ Persist
+ 1
+ Type
+ String
+ Value
+
+
+ AODefaultSwimDown
+
+ Comment
+ Default swimdown anim
+ Persist
+ 1
+ Type
+ String
+ Value
+
+
AODefaultStandUp
Comment
@@ -715,6 +770,17 @@
Value
-%Y-%m
+ ShowFavoritesOnLogin
+
+ Comment
+ Determines whether favorites of last logged in user will be saved on exit from viewer and shown on login screen
+ Persist
+ 1
+ Type
+ Boolean
+ Value
+ 1
+
KeywordsChangeColor
diff --git a/indra/newview/app_settings/windlight/postprocesseffects.xml b/indra/newview/app_settings/windlight/postprocesseffects.xml
index 1f3ee7755..bf917ab33 100644
--- a/indra/newview/app_settings/windlight/postprocesseffects.xml
+++ b/indra/newview/app_settings/windlight/postprocesseffects.xml
@@ -6,6 +6,8 @@
4.5799999237060547
bloom_width
12.539999961853027
+ gamma
+ 1.0
brightness
0.89999997615814209
brightness_multiplier
@@ -42,6 +44,8 @@
1.5
bloom_width
2.25
+ gamma
+ 1.0
brightness
1
brightness_multiplier
@@ -144,7 +148,7 @@
saturation
1
- default
+ Default
bloom_strength
1.5
@@ -173,12 +177,12 @@
0
enable_gauss_blur
0
- enable_posterize
- 0
- enable_motionblur
- 0
- enable_vignette
- 0
+ enable_posterize
+ 0
+ enable_motionblur
+ 0
+ enable_vignette
+ 0
gauss_blur_passes
2
extract_high
@@ -191,82 +195,20 @@
0.40000000000000002
saturation
1
- posterize_layers
- 10
- blur_strength
- 10
- vignette_strength
- 0.85
- vignette_radius
- 0.7
- vignette_darkness
- 1.0
- vignette_desaturation
- 1.0
- vignette_chromatic_aberration
- 0.01
-
- PyFx None
-
- bloom_strength
- 1.5
- bloom_width
- 2.25
- blur_strength
- 10
- brightness
- 1
- brightness_multiplier
- 3
- contrast
- 1
- contrast_base
-
- 1
- 1
- 1
- 0.5
-
- enable_bloom
- 0
- enable_color_filter
- 0
- enable_gauss_blur
- 0
- enable_motionblur
- 0
- enable_night_vision
- 0
- enable_posterize
- 0
- enable_vignette
- 0
- extract_high
- 1
- extract_low
- 0.949999999999999955591079
- gamma
- 1
- gauss_blur_passes
- 2
- noise_size
- 25
- noise_strength
- 0.4000000000000000222044605
posterize_layers
10
- saturation
- 1
- vignette_chromatic_aberration
- 0.01000000000000000020816682
- vignette_darkness
- 1
- vignette_desaturation
- 1
- vignette_radius
- 0.699999999999999955591079
+ blur_strength
+ 10
vignette_strength
- 0.8499999999999999777955395
+ 0.85
+ vignette_radius
+ 0.7
+ vignette_darkness
+ 1.0
+ vignette_desaturation
+ 1.0
+ vignette_chromatic_aberration
+ 0.01
PyFX CatVision v1
@@ -826,7 +768,7 @@
vignette_strength
1
- PyFX v1
+ PyFX Twilight v1 Cold
bloom_strength
1.5
@@ -835,15 +777,77 @@
blur_strength
30
brightness
- 1.19999992847442626953125
+ 1.25
brightness_multiplier
3
contrast
- 1.25
+ 1.0299999713897705078125
contrast_base
- 0.7999999523162841796875
- 0.89999997615814208984375
+ 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
@@ -866,7 +870,7 @@
extract_low
0.949999999999999955591079
gamma
- 2
+ 1.5
gauss_blur_passes
2
noise_size
@@ -876,15 +880,15 @@
posterize_layers
10
saturation
- 0.7999999523162841796875
+ 0.5
vignette_chromatic_aberration
- 0.004500000271946191787719727
+ 0.005000000353902578353881836
vignette_darkness
1
vignette_desaturation
- 0
+ 0.4000000059604644775390625
vignette_radius
- 1.5
+ 5
vignette_strength
1
@@ -950,7 +954,69 @@
vignette_strength
1
- PyFx default
+ 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
@@ -972,7 +1038,7 @@
1
enable_bloom
- 1
+ 0
enable_color_filter
1
enable_gauss_blur
@@ -1012,5 +1078,191 @@
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
+
diff --git a/indra/newview/app_settings/windlight/skies/Ambient%20%2BFog%20Black.xml b/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Ambient%20%2BFog%20Black.xml
similarity index 100%
rename from indra/newview/app_settings/windlight/skies/Ambient%20%2BFog%20Black.xml
rename to indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Ambient%20%2BFog%20Black.xml
diff --git a/indra/newview/app_settings/windlight/skies/Ambient%20%2BFog%20Dark%20Blue.xml b/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Ambient%20%2BFog%20Dark%20Blue.xml
similarity index 100%
rename from indra/newview/app_settings/windlight/skies/Ambient%20%2BFog%20Dark%20Blue.xml
rename to indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Ambient%20%2BFog%20Dark%20Blue.xml
diff --git a/indra/newview/app_settings/windlight/skies/Ambient%20%2BFog%20Dark.xml b/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Ambient%20%2BFog%20Dark.xml
similarity index 100%
rename from indra/newview/app_settings/windlight/skies/Ambient%20%2BFog%20Dark.xml
rename to indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Ambient%20%2BFog%20Dark.xml
diff --git a/indra/newview/app_settings/windlight/skies/Ambient%20%2BFog%20Gray%20Blue.xml b/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Ambient%20%2BFog%20Gray%20Blue.xml
similarity index 100%
rename from indra/newview/app_settings/windlight/skies/Ambient%20%2BFog%20Gray%20Blue.xml
rename to indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Ambient%20%2BFog%20Gray%20Blue.xml
diff --git a/indra/newview/app_settings/windlight/skies/Ambient%20%2BFog%20Gray.xml b/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Ambient%20%2BFog%20Gray.xml
similarity index 100%
rename from indra/newview/app_settings/windlight/skies/Ambient%20%2BFog%20Gray.xml
rename to indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Ambient%20%2BFog%20Gray.xml
diff --git a/indra/newview/app_settings/windlight/skies/Ambient%20%2BFog%20Underwater.xml b/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Ambient%20%2BFog%20Underwater.xml
similarity index 100%
rename from indra/newview/app_settings/windlight/skies/Ambient%20%2BFog%20Underwater.xml
rename to indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Ambient%20%2BFog%20Underwater.xml
diff --git a/indra/newview/app_settings/windlight/skies/Ambient%20%2BFog%20White%20Wash.xml b/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Ambient%20%2BFog%20White%20Wash.xml
similarity index 100%
rename from indra/newview/app_settings/windlight/skies/Ambient%20%2BFog%20White%20Wash.xml
rename to indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Ambient%20%2BFog%20White%20Wash.xml
diff --git a/indra/newview/app_settings/windlight/skies/Ambient%20%2BFog%20White.xml b/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Ambient%20%2BFog%20White.xml
similarity index 95%
rename from indra/newview/app_settings/windlight/skies/Ambient%20%2BFog%20White.xml
rename to indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Ambient%20%2BFog%20White.xml
index b33f7ad69..c91588466 100644
--- a/indra/newview/app_settings/windlight/skies/Ambient%20%2BFog%20White.xml
+++ b/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Ambient%20%2BFog%20White.xml
@@ -2,10 +2,10 @@
ambient
- 3
- 3
- 3
- 1
+ 1.5
+ 1.5
+ 1.5
+ 0.5
blue_density
@@ -63,14 +63,14 @@
density_multiplier
- 4.999999873689375817775726e-05
+ 0.0008999999845400452613830566
0
0
1
distance_multiplier
- 50
+ 1
0
0
1
diff --git a/indra/newview/app_settings/windlight/skies/Ambient%20Black.xml b/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Ambient%20Black.xml
similarity index 100%
rename from indra/newview/app_settings/windlight/skies/Ambient%20Black.xml
rename to indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Ambient%20Black.xml
diff --git a/indra/newview/app_settings/windlight/skies/Ambient%20Dark%20H%2DBomb.xml b/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Ambient%20Dark%20H%2DBomb.xml
similarity index 100%
rename from indra/newview/app_settings/windlight/skies/Ambient%20Dark%20H%2DBomb.xml
rename to indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Ambient%20Dark%20H%2DBomb.xml
diff --git a/indra/newview/app_settings/windlight/skies/Ambient%20Not%20As%20Dark.xml b/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Ambient%20Dark.xml
similarity index 100%
rename from indra/newview/app_settings/windlight/skies/Ambient%20Not%20As%20Dark.xml
rename to indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Ambient%20Dark.xml
diff --git a/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Ambient%20Gray%20Background.xml b/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Ambient%20Gray%20Background.xml
new file mode 100644
index 000000000..fe1c9f8c0
--- /dev/null
+++ b/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Ambient%20Gray%20Background.xml
@@ -0,0 +1,141 @@
+
+
+ ambient
+
+ 1.5
+ 1.5
+ 1.5
+ 0.5
+
+ blue_density
+
+ 0.449999993698308176082179
+ 0.4499999939833594919669224
+ 0.4499999944309046040480382
+ 1
+
+ blue_horizon
+
+ 0.89999997615814208984375
+ 0.89999997615814208984375
+ 0.89999997615814208984375
+ 0.449999988079071044921875
+
+ cloud_color
+
+ 0.2261540024157503436796901
+ 0.2261540024157503436796901
+ 0.2261540024157503436796901
+ 1
+
+ cloud_pos_density1
+
+ 0
+ 0
+ 0
+ 1
+
+ cloud_pos_density2
+
+ 0.5
+ 0.5
+ 0.125
+ 1
+
+ cloud_scale
+
+ 0.4199999868869781494140625
+ 0
+ 0
+ 1
+
+ cloud_scroll_rate
+
+ 10
+ 10
+
+ cloud_shadow
+
+ 0.36000001430511474609375
+ 0
+ 0
+ 1
+
+ density_multiplier
+
+ 0.0004499999922700226306915283
+ 0
+ 0
+ 1
+
+ distance_multiplier
+
+ 0
+ 0
+ 0
+ 1
+
+ east_angle
+ 0
+ enable_cloud_scroll
+
+ 1
+ 1
+
+ gamma
+
+ 1
+ 0
+ 0
+ 1
+
+ glow
+
+ 5
+ 0.001000000047497451305389404
+ -0
+ 1
+
+ haze_density
+
+ 4
+ 0
+ 0
+ 1
+
+ haze_horizon
+
+ 0
+ 0.1991560043746730401803546
+ 0.1991560043746730401803546
+ 1
+
+ lightnorm
+
+ -0
+ 1
+ 1.148381556959066074341536e-06
+ 0
+
+ max_y
+
+ 4000
+ 0
+ 0
+ 1
+
+ preset_num
+ 26
+ star_brightness
+ 0
+ sun_angle
+ 1.57079517841339111328125
+ sunlight_color
+
+ 0
+ 0
+ 0
+ 0
+
+
+
diff --git a/indra/newview/app_settings/windlight/skies/Ambient%20Gray.xml b/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Ambient%20Gray.xml
similarity index 100%
rename from indra/newview/app_settings/windlight/skies/Ambient%20Gray.xml
rename to indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Ambient%20Gray.xml
diff --git a/indra/newview/app_settings/windlight/skies/Ambient%20Not%20As%20White.xml b/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Ambient%20White.xml
similarity index 100%
rename from indra/newview/app_settings/windlight/skies/Ambient%20Not%20As%20White.xml
rename to indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Ambient%20White.xml
diff --git a/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Cloudy%20Afternoon.xml b/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Cloudy%20Afternoon.xml
index e839d6245..233a3b354 100644
--- a/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Cloudy%20Afternoon.xml
+++ b/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Cloudy%20Afternoon.xml
@@ -37,14 +37,14 @@
cloud_pos_density2
- 1.6884100437164306640625
+ 1
1
0
1
cloud_scale
- 0.07000000029802322387695313
+ 0.2000000029802322387695313
0
0
1
@@ -56,7 +56,7 @@
cloud_shadow
- 0.66999995708465576171875
+ 0.75
0
0
1
@@ -105,7 +105,7 @@
haze_horizon
- 0
+ 0.1499999910593032836914063
0.1991560012102127075195313
0.1991560012102127075195313
1
@@ -119,7 +119,7 @@
max_y
- 150
+ 1
0
0
1
diff --git a/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Cloudy%20Evening.xml b/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Cloudy%20Evening.xml
index 291e4691f..4039d2ee5 100644
--- a/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Cloudy%20Evening.xml
+++ b/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Cloudy%20Evening.xml
@@ -23,10 +23,10 @@
cloud_color
- 0.25
- 0.25
- 0.25
- 0.25
+ 0.2999999821186065673828125
+ 0.2999999821186065673828125
+ 0.2999999821186065673828125
+ 0.2999999821186065673828125
cloud_pos_density1
@@ -44,7 +44,7 @@
cloud_scale
- 0.07000000029802322387695313
+ 0.2000000029802322387695313
0
0
1
@@ -56,7 +56,7 @@
cloud_shadow
- 0.66999995708465576171875
+ 0.75
0
0
1
@@ -119,7 +119,7 @@
max_y
- 150
+ 1
0
0
1
diff --git a/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Cloudy%20Noon.xml b/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Cloudy%20Noon.xml
new file mode 100644
index 000000000..60882441d
--- /dev/null
+++ b/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Cloudy%20Noon.xml
@@ -0,0 +1,141 @@
+
+
+ ambient
+
+ 0.2999999821186065673828125
+ 0.44999992847442626953125
+ 0.599999964237213134765625
+ 0.199999988079071044921875
+
+ blue_density
+
+ 2
+ 2
+ 2
+ 1
+
+ blue_horizon
+
+ 0.599999964237213134765625
+ 0.599999964237213134765625
+ 0.599999964237213134765625
+ 0.2999999821186065673828125
+
+ cloud_color
+
+ 0.329999983310699462890625
+ 0.329999983310699462890625
+ 0.329999983310699462890625
+ 0.329999983310699462890625
+
+ cloud_pos_density1
+
+ 1
+ 1
+ 0.25
+ 1
+
+ cloud_pos_density2
+
+ 1.6884100437164306640625
+ 1
+ 0
+ 1
+
+ cloud_scale
+
+ 0.2000000029802322387695313
+ 0
+ 0
+ 1
+
+ cloud_scroll_rate
+
+ 10.3999996185302734375
+ 10
+
+ cloud_shadow
+
+ 0.75
+ 0
+ 0
+ 1
+
+ density_multiplier
+
+ 9.999999747378751635551453e-05
+ 0
+ 0
+ 1
+
+ distance_multiplier
+
+ 5
+ 0
+ 0
+ 1
+
+ east_angle
+ 0
+ enable_cloud_scroll
+
+ 1
+ 1
+
+ gamma
+
+ 0.89999997615814208984375
+ 0
+ 0
+ 1
+
+ glow
+
+ 0.200002193450927734375
+ 0.001000000047497451305389404
+ -0.199999988079071044921875
+ 1
+
+ haze_density
+
+ 4
+ 0
+ 0
+ 1
+
+ haze_horizon
+
+ 0.2099999934434890747070313
+ 0.1991560012102127075195313
+ 0.1991560012102127075195313
+ 1
+
+ lightnorm
+
+ 0
+ 1
+ -4.371138828673792886547744e-08
+ 0
+
+ max_y
+
+ 1
+ 0
+ 0
+ 1
+
+ preset_num
+ 22
+ star_brightness
+ 0
+ sun_angle
+ 1.57079637050628662109375
+ sunlight_color
+
+ 1.0499999523162841796875
+ 1.0499999523162841796875
+ 1.0499999523162841796875
+ 0.3499999940395355224609375
+
+
+
diff --git a/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Cloudy%20Rainy%20Bright.xml b/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Cloudy%20Rainy%20Bright.xml
new file mode 100644
index 000000000..409cea7e3
--- /dev/null
+++ b/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Cloudy%20Rainy%20Bright.xml
@@ -0,0 +1,141 @@
+
+
+ ambient
+
+ 0
+ 0
+ 0
+ 0
+
+ blue_density
+
+ 2
+ 2
+ 2
+ 2
+
+ blue_horizon
+
+ 0.39999997615814208984375
+ 0.39999997615814208984375
+ 0.39999997615814208984375
+ 0.199999988079071044921875
+
+ cloud_color
+
+ 0.2999999821186065673828125
+ 0.2999999821186065673828125
+ 0.2999999821186065673828125
+ 0.2999999821186065673828125
+
+ cloud_pos_density1
+
+ 0.5
+ 0.5
+ 0.1700000017881393432617188
+ 1
+
+ cloud_pos_density2
+
+ 1.6884100437164306640625
+ 1
+ 0
+ 1
+
+ cloud_scale
+
+ 0.2000000029802322387695313
+ 0
+ 0
+ 1
+
+ cloud_scroll_rate
+
+ 10.3999996185302734375
+ 10
+
+ cloud_shadow
+
+ 0.75
+ 0
+ 0
+ 1
+
+ density_multiplier
+
+ 0.0005999999702908098697662354
+ 0
+ 0
+ 1
+
+ distance_multiplier
+
+ 3.5
+ 0
+ 0
+ 1
+
+ east_angle
+ 0
+ enable_cloud_scroll
+
+ 1
+ 1
+
+ gamma
+
+ 1.599999904632568359375
+ 0
+ 0
+ 1
+
+ glow
+
+ 0.200002193450927734375
+ 0.001000000047497451305389404
+ -0.1499999910593032836914063
+ 1
+
+ haze_density
+
+ 4
+ 0
+ 0
+ 1
+
+ haze_horizon
+
+ 0.04999999701976776123046875
+ 0.1991560012102127075195313
+ 0.1991560012102127075195313
+ 1
+
+ lightnorm
+
+ 0
+ 0.876306593418121337890625
+ -0.4817537963390350341796875
+ 0
+
+ max_y
+
+ 26
+ 0
+ 0
+ 1
+
+ preset_num
+ 22
+ star_brightness
+ 0
+ sun_angle
+ 2.0734512805938720703125
+ sunlight_color
+
+ 0.599999964237213134765625
+ 0.75
+ 0.749999940395355224609375
+ 0.75
+
+
+
diff --git a/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Cloudy%20Rainy%20HalfBright.xml b/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Cloudy%20Rainy%20HalfBright.xml
new file mode 100644
index 000000000..eee637388
--- /dev/null
+++ b/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Cloudy%20Rainy%20HalfBright.xml
@@ -0,0 +1,141 @@
+
+
+ ambient
+
+ 0
+ 0
+ 0
+ 0
+
+ blue_density
+
+ 2
+ 2
+ 2
+ 2
+
+ blue_horizon
+
+ 0.39999997615814208984375
+ 0.39999997615814208984375
+ 0.39999997615814208984375
+ 0.199999988079071044921875
+
+ cloud_color
+
+ 0.2999999821186065673828125
+ 0.2999999821186065673828125
+ 0.2999999821186065673828125
+ 0.2999999821186065673828125
+
+ cloud_pos_density1
+
+ 0.5
+ 0.5
+ 0.1700000017881393432617188
+ 1
+
+ cloud_pos_density2
+
+ 1.6884100437164306640625
+ 1
+ 0
+ 1
+
+ cloud_scale
+
+ 0.2000000029802322387695313
+ 0
+ 0
+ 1
+
+ cloud_scroll_rate
+
+ 10.3999996185302734375
+ 10
+
+ cloud_shadow
+
+ 0.75
+ 0
+ 0
+ 1
+
+ density_multiplier
+
+ 0.0005999999702908098697662354
+ 0
+ 0
+ 1
+
+ distance_multiplier
+
+ 3.5
+ 0
+ 0
+ 1
+
+ east_angle
+ 0
+ enable_cloud_scroll
+
+ 1
+ 1
+
+ gamma
+
+ 1.19999992847442626953125
+ 0
+ 0
+ 1
+
+ glow
+
+ 0.200002193450927734375
+ 0.001000000047497451305389404
+ -0.1499999910593032836914063
+ 1
+
+ haze_density
+
+ 4
+ 0
+ 0
+ 1
+
+ haze_horizon
+
+ 0.04999999701976776123046875
+ 0.1991560012102127075195313
+ 0.1991560012102127075195313
+ 1
+
+ lightnorm
+
+ 0
+ 0.876306593418121337890625
+ -0.4817537963390350341796875
+ 0
+
+ max_y
+
+ 100
+ 0
+ 0
+ 1
+
+ preset_num
+ 22
+ star_brightness
+ 0
+ sun_angle
+ 2.0734512805938720703125
+ sunlight_color
+
+ 0.599999964237213134765625
+ 0.75
+ 0.749999940395355224609375
+ 0.75
+
+
+
diff --git a/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Cloudy%20Rainy.xml b/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Cloudy%20Rainy.xml
index 9ba62cce2..1b1fd7488 100644
--- a/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Cloudy%20Rainy.xml
+++ b/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Cloudy%20Rainy.xml
@@ -30,9 +30,9 @@
cloud_pos_density1
- 1
- 1
- 0.2999999821186065673828125
+ 0.5
+ 0.5
+ 0.1700000017881393432617188
1
cloud_pos_density2
@@ -44,33 +44,33 @@
cloud_scale
- 0.07000000029802322387695313
+ 0.2000000029802322387695313
0
0
1
cloud_scroll_rate
- 11
+ 10.3999996185302734375
10
cloud_shadow
- 0.66999995708465576171875
+ 0.75
0
0
1
density_multiplier
- 0.0003999999898951500654220581
+ 0.0005999999702908098697662354
0
0
1
distance_multiplier
- 6
+ 3.5
0
0
1
@@ -93,7 +93,7 @@
0.200002193450927734375
0.001000000047497451305389404
- -0.2499999850988388061523438
+ -0.1499999910593032836914063
1
haze_density
@@ -105,7 +105,7 @@
haze_horizon
- 0
+ 0.04999999701976776123046875
0.1991560012102127075195313
0.1991560012102127075195313
1
@@ -119,7 +119,7 @@
max_y
- 70
+ 100
0
0
1
diff --git a/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Default%20.xml b/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Default%20.xml
index 722a18847..b26c41ae1 100644
--- a/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Default%20.xml
+++ b/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Default%20.xml
@@ -2,49 +2,49 @@
ambient
+ 0.2880000174045562744140625
+ 0.449999988079071044921875
+ 0.599999964237213134765625
0.599999964237213134765625
- 1.0499999523162841796875
- 1.19999992847442626953125
- 1.19999992847442626953125
blue_density
0.199999988079071044921875
0.2999999821186065673828125
- 0.39999997615814208984375
- 0.699999988079071044921875
+ 0.599999964237213134765625
+ 0.2999999821186065673828125
blue_horizon
- 0.39999997615814208984375
- 0.5
- 1
- 0.5
+ 0
+ 0.199999988079071044921875
+ 0.2999999821186065673828125
+ 0.2999999821186065673828125
cloud_color
- 0.2399999797344207763671875
- 0.2399999797344207763671875
- 0.2399999797344207763671875
- 0.2399999946355819702148438
+ 1
+ 1
+ 1
+ 1
cloud_pos_density1
1
1
- 0.329999983310699462890625
+ 0.08999999612569808959960938
1
cloud_pos_density2
1.6884100437164306640625
0
- 0.04999999701976776123046875
+ 0.75
1
cloud_scale
- 0.0999999940395355224609375
+ 0.4999999701976776123046875
0
0
1
@@ -63,14 +63,14 @@
density_multiplier
- 9.999999747378751635551453e-05
+ 0.0002500000118743628263473511
0
0
1
distance_multiplier
- 6
+ 1
0
0
1
@@ -84,28 +84,28 @@
gamma
- 0.5
+ 0.75
0
0
1
glow
- 5
+ 10
0.001000000047497451305389404
- -0.4799999892711639404296875
+ -0.4999999701976776123046875
1
haze_density
- 1
+ 0.199999988079071044921875
0
0
1
haze_horizon
- 0.199999988079071044921875
+ 0.4699999988079071044921875
0.1991560012102127075195313
0.1991560012102127075195313
1
@@ -113,13 +113,13 @@
lightnorm
0
- 0.876306593418121337890625
- -0.4817537963390350341796875
+ 0.867070615291595458984375
+ -0.49818527698516845703125
0
max_y
- 4000
+ 2000
0
0
1
@@ -129,13 +129,13 @@
star_brightness
0
sun_angle
- 2.0734512805938720703125
+ 2.092300891876220703125
sunlight_color
- 1.7999999523162841796875
- 1.61999976634979248046875
- 1.43999946117401123046875
- 0.599999964237213134765625
+ 1.5
+ 1.5
+ 1.5
+ 0.5
diff --git a/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Fine%20Afternoon.xml b/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Fine%20Afternoon.xml
index fc2d3ea8e..438cfe90b 100644
--- a/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Fine%20Afternoon.xml
+++ b/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Fine%20Afternoon.xml
@@ -3,55 +3,55 @@
ambient
0.599999964237213134765625
- 1.0499999523162841796875
- 1.19999992847442626953125
+ 1.049999237060546875
1.19999992847442626953125
+ 0.39999997615814208984375
blue_density
- 0.199999988079071044921875
+ 0.0999999940395355224609375
0.2999999821186065673828125
0.39999997615814208984375
- 0.699999988079071044921875
+ 0.560000002384185791015625
blue_horizon
0.39999997615814208984375
- 0.5
- 1
- 0.5
+ 0.39999997615814208984375
+ 0.7999999523162841796875
+ 0.39999997615814208984375
cloud_color
- 0.2399999797344207763671875
- 0.2399999797344207763671875
- 0.2399999797344207763671875
- 0.2399999946355819702148438
+ 0.39999997615814208984375
+ 0.2800000011920928955078125
+ 0.1999999433755874633789063
+ 0.39999997615814208984375
cloud_pos_density1
1
1
- 0.329999983310699462890625
+ 0.0999999940395355224609375
1
cloud_pos_density2
1.6884100437164306640625
0
- 0.04999999701976776123046875
+ 0.0999999940395355224609375
1
cloud_scale
- 0.0999999940395355224609375
+ 0.05999999493360519409179688
0
0
1
cloud_scroll_rate
- 10.19999980926513671875
+ 10.5
10.0109996795654296875
cloud_shadow
@@ -84,28 +84,28 @@
gamma
- 0.5
+ 0.599999964237213134765625
0
0
1
glow
- 21.8000011444091796875
+ 20
0.001000000047497451305389404
- -0.2499999850988388061523438
+ -1.25
1
haze_density
- 1
+ 0.5
0
0
1
haze_horizon
- 0.199999988079071044921875
+ 0.2999999821186065673828125
0.1991560012102127075195313
0.1991560012102127075195313
1
@@ -132,10 +132,10 @@
2.51327419281005859375
sunlight_color
- 2.25
- 1.68749940395355224609375
- 1.125
- 0.75
+ 1.5
+ 1.19999992847442626953125
+ 0.89999997615814208984375
+ 1.5
diff --git a/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Flamesight.xml b/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Flamesight.xml
new file mode 100644
index 000000000..aafbc189f
--- /dev/null
+++ b/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Flamesight.xml
@@ -0,0 +1,141 @@
+
+
+ ambient
+
+ 0
+ 0
+ 0
+ 0
+
+ blue_density
+
+ 0
+ 0
+ 1.5
+ 1.5
+
+ blue_horizon
+
+ 0
+ 0
+ 2
+ 2
+
+ cloud_color
+
+ 0.5
+ 0.5
+ 0.5
+ 0.5
+
+ cloud_pos_density1
+
+ 1.6884100437164306640625
+ 0
+ 0.5
+ 1
+
+ cloud_pos_density2
+
+ 1.6884100437164306640625
+ 0.526096999645233154296875
+ 0
+ 1
+
+ cloud_scale
+
+ 0.0999999940395355224609375
+ 0
+ 0
+ 1
+
+ cloud_scroll_rate
+
+ 10.19999980926513671875
+ 10.0109996795654296875
+
+ cloud_shadow
+
+ 0.5
+ 0
+ 0
+ 1
+
+ density_multiplier
+
+ 0.0003299999807495623826980591
+ 0
+ 0
+ 1
+
+ distance_multiplier
+
+ 50
+ 0
+ 0
+ 1
+
+ east_angle
+ 0
+ enable_cloud_scroll
+
+ 1
+ 1
+
+ gamma
+
+ 0.329999983310699462890625
+ 0
+ 0
+ 1
+
+ glow
+
+ 30
+ 0.001000000047497451305389404
+ -0.4999999701976776123046875
+ 1
+
+ haze_density
+
+ 1
+ 0
+ 0
+ 1
+
+ haze_horizon
+
+ 0.5
+ 0.1991560012102127075195313
+ 0.1991560012102127075195313
+ 1
+
+ lightnorm
+
+ 0
+ 0.867070615291595458984375
+ -0.49818527698516845703125
+ 0
+
+ max_y
+
+ 2000
+ 0
+ 0
+ 1
+
+ preset_num
+ 22
+ star_brightness
+ 0
+ sun_angle
+ 2.092300891876220703125
+ sunlight_color
+
+ 3
+ 0.990000188350677490234375
+ 0
+ 1
+
+
+
diff --git a/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Indoors%20Bright.xml b/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Indoors%20Bright.xml
new file mode 100644
index 000000000..16ce75e17
--- /dev/null
+++ b/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Indoors%20Bright.xml
@@ -0,0 +1,141 @@
+
+
+ ambient
+
+ 2.25
+ 2.25
+ 2.25
+ 0.75
+
+ blue_density
+
+ 2
+ 2
+ 2
+ 2
+
+ blue_horizon
+
+ 0.1999999731779098510742188
+ 0.1999999731779098510742188
+ 0.1999999731779098510742188
+ 0.0999999940395355224609375
+
+ cloud_color
+
+ 1
+ 1
+ 1
+ 1
+
+ cloud_pos_density1
+
+ 1
+ 1
+ 0.08999999612569808959960938
+ 1
+
+ cloud_pos_density2
+
+ 1.6884100437164306640625
+ 0
+ 0.75
+ 1
+
+ cloud_scale
+
+ 0.4999999701976776123046875
+ 0
+ 0
+ 1
+
+ cloud_scroll_rate
+
+ 10.19999980926513671875
+ 10.0109996795654296875
+
+ cloud_shadow
+
+ 1
+ 0
+ 0
+ 1
+
+ density_multiplier
+
+ 9.999999747378751635551453e-06
+ 0
+ 0
+ 1
+
+ distance_multiplier
+
+ 100
+ 0
+ 0
+ 1
+
+ east_angle
+ 0
+ enable_cloud_scroll
+
+ 1
+ 1
+
+ gamma
+
+ 0.66999995708465576171875
+ 0
+ 0
+ 1
+
+ glow
+
+ 10
+ 0.001000000047497451305389404
+ -0.4999999701976776123046875
+ 1
+
+ haze_density
+
+ 1
+ 0
+ 0
+ 1
+
+ haze_horizon
+
+ 1
+ 0.1991560012102127075195313
+ 0.1991560012102127075195313
+ 1
+
+ lightnorm
+
+ 0
+ 0.867070615291595458984375
+ -0.49818527698516845703125
+ 0
+
+ max_y
+
+ 4000
+ 0
+ 0
+ 1
+
+ preset_num
+ 22
+ star_brightness
+ 0
+ sun_angle
+ 2.092300891876220703125
+ sunlight_color
+
+ 3
+ 2.4000003337860107421875
+ 2.099999904632568359375
+ 1
+
+
+
diff --git a/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Indoors%20Cloudy.xml b/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Indoors%20Cloudy.xml
new file mode 100644
index 000000000..40bbf3b88
--- /dev/null
+++ b/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Indoors%20Cloudy.xml
@@ -0,0 +1,141 @@
+
+
+ ambient
+
+ 1.5
+ 1.7999999523162841796875
+ 2.099999904632568359375
+ 2.099999904632568359375
+
+ blue_density
+
+ 2
+ 2
+ 2
+ 2
+
+ blue_horizon
+
+ 0.1999999731779098510742188
+ 0.1999999731779098510742188
+ 0.1999999731779098510742188
+ 0.0999999940395355224609375
+
+ cloud_color
+
+ 1
+ 1
+ 1
+ 1
+
+ cloud_pos_density1
+
+ 1
+ 1
+ 0.08999999612569808959960938
+ 1
+
+ cloud_pos_density2
+
+ 1.6884100437164306640625
+ 0
+ 0.75
+ 1
+
+ cloud_scale
+
+ 0.4999999701976776123046875
+ 0
+ 0
+ 1
+
+ cloud_scroll_rate
+
+ 10.19999980926513671875
+ 10.0109996795654296875
+
+ cloud_shadow
+
+ 1
+ 0
+ 0
+ 1
+
+ density_multiplier
+
+ 1.999999949475750327110291e-05
+ 0
+ 0
+ 1
+
+ distance_multiplier
+
+ 100
+ 0
+ 0
+ 1
+
+ east_angle
+ 0
+ enable_cloud_scroll
+
+ 1
+ 1
+
+ gamma
+
+ 0.66999995708465576171875
+ 0
+ 0
+ 1
+
+ glow
+
+ 10
+ 0.001000000047497451305389404
+ -0.4999999701976776123046875
+ 1
+
+ haze_density
+
+ 1
+ 0
+ 0
+ 1
+
+ haze_horizon
+
+ 1
+ 0.1991560012102127075195313
+ 0.1991560012102127075195313
+ 1
+
+ lightnorm
+
+ 0
+ 0.867070615291595458984375
+ -0.49818527698516845703125
+ 0
+
+ max_y
+
+ 4000
+ 0
+ 0
+ 1
+
+ preset_num
+ 22
+ star_brightness
+ 0
+ sun_angle
+ 2.092300891876220703125
+ sunlight_color
+
+ 1.230000019073486328125
+ 1.230000019073486328125
+ 1.230000019073486328125
+ 0.4099999964237213134765625
+
+
+
diff --git a/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Indoors%20Evening.xml b/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Indoors%20Evening.xml
new file mode 100644
index 000000000..c10d7dc87
--- /dev/null
+++ b/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Indoors%20Evening.xml
@@ -0,0 +1,141 @@
+
+
+ ambient
+
+ 0.2999999821186065673828125
+ 0.599999964237213134765625
+ 0.89999997615814208984375
+ 0.89999997615814208984375
+
+ blue_density
+
+ 2
+ 2
+ 2
+ 2
+
+ blue_horizon
+
+ 0.1999999731779098510742188
+ 0.1999999731779098510742188
+ 0.1999999731779098510742188
+ 0.0999999940395355224609375
+
+ cloud_color
+
+ 0.5
+ 0.5
+ 0.5
+ 0.5
+
+ cloud_pos_density1
+
+ 1
+ 1
+ 0.08999999612569808959960938
+ 1
+
+ cloud_pos_density2
+
+ 1.6884100437164306640625
+ 0
+ 0.75
+ 1
+
+ cloud_scale
+
+ 0.4999999701976776123046875
+ 0
+ 0
+ 1
+
+ cloud_scroll_rate
+
+ 10.19999980926513671875
+ 10.0109996795654296875
+
+ cloud_shadow
+
+ 1
+ 0
+ 0
+ 1
+
+ density_multiplier
+
+ 1.999999949475750327110291e-05
+ 0
+ 0
+ 1
+
+ distance_multiplier
+
+ 100
+ 0
+ 0
+ 1
+
+ east_angle
+ 0
+ enable_cloud_scroll
+
+ 1
+ 1
+
+ gamma
+
+ 0.66999995708465576171875
+ 0
+ 0
+ 1
+
+ glow
+
+ 10
+ 0.001000000047497451305389404
+ -0.4999999701976776123046875
+ 1
+
+ haze_density
+
+ 1
+ 0
+ 0
+ 1
+
+ haze_horizon
+
+ 1
+ 0.1991560012102127075195313
+ 0.1991560012102127075195313
+ 1
+
+ lightnorm
+
+ 0
+ 0
+ -1
+ 0
+
+ max_y
+
+ 4000
+ 0
+ 0
+ 1
+
+ preset_num
+ 22
+ star_brightness
+ 0
+ sun_angle
+ 3.1415927410125732421875
+ sunlight_color
+
+ 0
+ 0
+ 0
+ 0
+
+
+
diff --git a/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Indoors%20Night.xml b/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Indoors%20Night.xml
new file mode 100644
index 000000000..2958cad7e
--- /dev/null
+++ b/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Indoors%20Night.xml
@@ -0,0 +1,141 @@
+
+
+ ambient
+
+ 0.599999964237213134765625
+ 0.75
+ 1.19999992847442626953125
+ 0.39999997615814208984375
+
+ blue_density
+
+ 1.99999988079071044921875
+ 1.99999988079071044921875
+ 1.99999988079071044921875
+ 1
+
+ blue_horizon
+
+ 0
+ 0
+ 0
+ 0
+
+ cloud_color
+
+ 0.5
+ 0.5
+ 0.5
+ 0.5
+
+ cloud_pos_density1
+
+ 1
+ 1
+ 0.08999999612569808959960938
+ 1
+
+ cloud_pos_density2
+
+ 1.6884100437164306640625
+ 0
+ 0.75
+ 1
+
+ cloud_scale
+
+ 0.4999999701976776123046875
+ 0
+ 0
+ 1
+
+ cloud_scroll_rate
+
+ 10.19999980926513671875
+ 10.0109996795654296875
+
+ cloud_shadow
+
+ 0
+ 0
+ 0
+ 1
+
+ density_multiplier
+
+ 0.0002500000118743628263473511
+ 0
+ 0
+ 1
+
+ distance_multiplier
+
+ 100
+ 0
+ 0
+ 1
+
+ east_angle
+ 0
+ enable_cloud_scroll
+
+ 1
+ 1
+
+ gamma
+
+ 0.66999995708465576171875
+ 0
+ 0
+ 1
+
+ glow
+
+ 10
+ 0.001000000047497451305389404
+ -0.4999999701976776123046875
+ 1
+
+ haze_density
+
+ 1
+ 0
+ 0
+ 1
+
+ haze_horizon
+
+ 0
+ 0.1991560012102127075195313
+ 0.1991560012102127075195313
+ 1
+
+ lightnorm
+
+ 0
+ 0
+ -1
+ 0
+
+ max_y
+
+ 4000
+ 0
+ 0
+ 1
+
+ preset_num
+ 22
+ star_brightness
+ 0
+ sun_angle
+ 3.1415927410125732421875
+ sunlight_color
+
+ 0
+ 0
+ 0
+ 0
+
+
+
diff --git a/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Night%20Bright.xml b/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Night%20Bright.xml
new file mode 100644
index 000000000..7b4cebdb9
--- /dev/null
+++ b/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Night%20Bright.xml
@@ -0,0 +1,141 @@
+
+
+ ambient
+
+ 0
+ 0.1499999910593032836914063
+ 0.4500000178813934326171875
+ 0.1499999910593032836914063
+
+ blue_density
+
+ 0.39999997615814208984375
+ 0.39999997615814208984375
+ 0.39999997615814208984375
+ 0.199999988079071044921875
+
+ blue_horizon
+
+ 0.4000000059604644775390625
+ 0.599999725818634033203125
+ 0.800000011920928955078125
+ 0.39999997615814208984375
+
+ cloud_color
+
+ 0.329999983310699462890625
+ 0.329999983310699462890625
+ 0.329999983310699462890625
+ 0.329999983310699462890625
+
+ cloud_pos_density1
+
+ 0.5
+ 0.5
+ 0.0999999940395355224609375
+ 1
+
+ cloud_pos_density2
+
+ 0.5
+ 0.5
+ 0
+ 1
+
+ cloud_scale
+
+ 0.07000000029802322387695313
+ 0
+ 0
+ 1
+
+ cloud_scroll_rate
+
+ 10.1399993896484375
+ 10.0109996795654296875
+
+ cloud_shadow
+
+ 0.39999997615814208984375
+ 0
+ 0
+ 1
+
+ density_multiplier
+
+ 4.999999873689375817775726e-05
+ 0
+ 0
+ 1
+
+ distance_multiplier
+
+ 10
+ 0
+ 0
+ 1
+
+ east_angle
+ 0
+ enable_cloud_scroll
+
+ 1
+ 1
+
+ gamma
+
+ 2
+ 0
+ 0
+ 1
+
+ glow
+
+ 20
+ 0.001000000047497451305389404
+ -1.25
+ 1
+
+ haze_density
+
+ 2
+ 0
+ 0
+ 1
+
+ haze_horizon
+
+ 0.04999999701976776123046875
+ 0.1991560012102127075195313
+ 0.1991560012102127075195313
+ 1
+
+ lightnorm
+
+ -0
+ 0.3090172111988067626953125
+ 0.951056420803070068359375
+ 1
+
+ max_y
+
+ 4000
+ 0
+ 0
+ 1
+
+ preset_num
+ 10
+ star_brightness
+ 0.5
+ sun_angle
+ 3.4557521343231201171875
+ sunlight_color
+
+ 0.08999999612569808959960938
+ 0.1799999922513961791992188
+ 0.2999999821186065673828125
+ 0.0999999940395355224609375
+
+
+
diff --git a/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Night%20City%20Bright.xml b/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Night%20City%20Bright.xml
new file mode 100644
index 000000000..19951bad6
--- /dev/null
+++ b/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Night%20City%20Bright.xml
@@ -0,0 +1,141 @@
+
+
+ ambient
+
+ 0
+ 0.1499999910593032836914063
+ 0.449999988079071044921875
+ 0.449999988079071044921875
+
+ blue_density
+
+ 0.39999997615814208984375
+ 0.39999997615814208984375
+ 0.39999997615814208984375
+ 0.199999988079071044921875
+
+ blue_horizon
+
+ 0.7999999523162841796875
+ 0.599999964237213134765625
+ 0.39999997615814208984375
+ 0.39999997615814208984375
+
+ cloud_color
+
+ 0.699999988079071044921875
+ 0.39999997615814208984375
+ 0.2999999821186065673828125
+ 0.699999988079071044921875
+
+ cloud_pos_density1
+
+ 0.5
+ 0.5
+ 0.04999999701976776123046875
+ 1
+
+ cloud_pos_density2
+
+ 0.5
+ 0.5
+ 0
+ 1
+
+ cloud_scale
+
+ 0.07000000029802322387695313
+ 0
+ 0
+ 1
+
+ cloud_scroll_rate
+
+ 10.1399993896484375
+ 10.0109996795654296875
+
+ cloud_shadow
+
+ 0.5
+ 0
+ 0
+ 1
+
+ density_multiplier
+
+ 4.999999873689375817775726e-05
+ 0
+ 0
+ 1
+
+ distance_multiplier
+
+ 10
+ 0
+ 0
+ 1
+
+ east_angle
+ 0
+ enable_cloud_scroll
+
+ 1
+ 1
+
+ gamma
+
+ 2
+ 0
+ 0
+ 1
+
+ glow
+
+ 20
+ 0.001000000047497451305389404
+ -1.25
+ 1
+
+ haze_density
+
+ 2
+ 0
+ 0
+ 1
+
+ haze_horizon
+
+ 0.04999999701976776123046875
+ 0.1991560012102127075195313
+ 0.1991560012102127075195313
+ 1
+
+ lightnorm
+
+ -0
+ 0.3090172111988067626953125
+ 0.951056420803070068359375
+ 1
+
+ max_y
+
+ 4000
+ 0
+ 0
+ 1
+
+ preset_num
+ 10
+ star_brightness
+ 0.5
+ sun_angle
+ 3.4557521343231201171875
+ sunlight_color
+
+ 0.1799999922513961791992188
+ 0.1799999922513961791992188
+ 0.1799999922513961791992188
+ 0.1799999922513961791992188
+
+
+
diff --git a/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Night%20City.xml b/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Night%20City.xml
new file mode 100644
index 000000000..8fa2e039f
--- /dev/null
+++ b/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Night%20City.xml
@@ -0,0 +1,141 @@
+
+
+ ambient
+
+ 0
+ 0.1499999910593032836914063
+ 0.449999988079071044921875
+ 0.449999988079071044921875
+
+ blue_density
+
+ 0.39999997615814208984375
+ 0.39999997615814208984375
+ 0.39999997615814208984375
+ 0.199999988079071044921875
+
+ blue_horizon
+
+ 0.7999999523162841796875
+ 0.599999964237213134765625
+ 0.39999997615814208984375
+ 0.39999997615814208984375
+
+ cloud_color
+
+ 0.699999988079071044921875
+ 0.39999997615814208984375
+ 0.2999999821186065673828125
+ 0.699999988079071044921875
+
+ cloud_pos_density1
+
+ 0.5
+ 0.5
+ 0.04999999701976776123046875
+ 1
+
+ cloud_pos_density2
+
+ 0.5
+ 0.5
+ 0
+ 1
+
+ cloud_scale
+
+ 0.07000000029802322387695313
+ 0
+ 0
+ 1
+
+ cloud_scroll_rate
+
+ 10.1399993896484375
+ 10.0109996795654296875
+
+ cloud_shadow
+
+ 0.5
+ 0
+ 0
+ 1
+
+ density_multiplier
+
+ 4.999999873689375817775726e-05
+ 0
+ 0
+ 1
+
+ distance_multiplier
+
+ 10
+ 0
+ 0
+ 1
+
+ east_angle
+ 0
+ enable_cloud_scroll
+
+ 1
+ 1
+
+ gamma
+
+ 1
+ 0
+ 0
+ 1
+
+ glow
+
+ 20
+ 0.001000000047497451305389404
+ -1.25
+ 1
+
+ haze_density
+
+ 2
+ 0
+ 0
+ 1
+
+ haze_horizon
+
+ 0.04999999701976776123046875
+ 0.1991560012102127075195313
+ 0.1991560012102127075195313
+ 1
+
+ lightnorm
+
+ -0
+ 0.3090172111988067626953125
+ 0.951056420803070068359375
+ 1
+
+ max_y
+
+ 4000
+ 0
+ 0
+ 1
+
+ preset_num
+ 10
+ star_brightness
+ 0.5
+ sun_angle
+ 3.4557521343231201171875
+ sunlight_color
+
+ 0.1799999922513961791992188
+ 0.1799999922513961791992188
+ 0.1799999922513961791992188
+ 0.1799999922513961791992188
+
+
+
diff --git a/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Night%20Rainy.xml b/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Night%20Rainy.xml
new file mode 100644
index 000000000..522c66109
--- /dev/null
+++ b/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Night%20Rainy.xml
@@ -0,0 +1,141 @@
+
+
+ ambient
+
+ 0
+ 0
+ 0
+ 0
+
+ blue_density
+
+ 2
+ 2
+ 2
+ 1
+
+ blue_horizon
+
+ 0.1999999731779098510742188
+ 0.1999999731779098510742188
+ 0.1999999731779098510742188
+ 0.0999999940395355224609375
+
+ cloud_color
+
+ 0.2999999821186065673828125
+ 0.2999999821186065673828125
+ 0.2999999821186065673828125
+ 0.2999999821186065673828125
+
+ cloud_pos_density1
+
+ 1
+ 1
+ 0.2999999821186065673828125
+ 1
+
+ cloud_pos_density2
+
+ 1.6884100437164306640625
+ 1
+ 0
+ 1
+
+ cloud_scale
+
+ 0.07000000029802322387695313
+ 0
+ 0
+ 1
+
+ cloud_scroll_rate
+
+ 11
+ 10
+
+ cloud_shadow
+
+ 0.66999995708465576171875
+ 0
+ 0
+ 1
+
+ density_multiplier
+
+ 0.0008999999845400452613830566
+ 0
+ 0
+ 1
+
+ distance_multiplier
+
+ 32.200000762939453125
+ 0
+ 0
+ 1
+
+ east_angle
+ 0
+ enable_cloud_scroll
+
+ 1
+ 1
+
+ gamma
+
+ 0.39999997615814208984375
+ 0
+ 0
+ 1
+
+ glow
+
+ 0.200002193450927734375
+ 0.001000000047497451305389404
+ -0.2499999850988388061523438
+ 1
+
+ haze_density
+
+ 0
+ 0
+ 0
+ 1
+
+ haze_horizon
+
+ 0.0999999940395355224609375
+ 0.1991560012102127075195313
+ 0.1991560012102127075195313
+ 1
+
+ lightnorm
+
+ 0
+ 0.876306593418121337890625
+ -0.4817537963390350341796875
+ 0
+
+ max_y
+
+ 314
+ 0
+ 0
+ 1
+
+ preset_num
+ 22
+ star_brightness
+ 0
+ sun_angle
+ 2.0734512805938720703125
+ sunlight_color
+
+ 0.08999998867511749267578125
+ 0.1799999773502349853515625
+ 0.269999980926513671875
+ 0.08999999612569808959960938
+
+
+
diff --git a/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Night.xml b/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Night.xml
index 3b4c08934..a1be61d2f 100644
--- a/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Night.xml
+++ b/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Night.xml
@@ -2,10 +2,10 @@
ambient
- 0.2999999821186065673828125
- 0.449999988079071044921875
- 0.599999964237213134765625
- 0.199999988079071044921875
+ 0
+ 0.1499999910593032836914063
+ 0.4500000178813934326171875
+ 0.1499999910593032836914063
blue_density
@@ -16,23 +16,23 @@
blue_horizon
- 0.199999988079071044921875
- 0.2999999821186065673828125
+ 0.4000000059604644775390625
+ 0.599999725818634033203125
+ 0.800000011920928955078125
0.39999997615814208984375
- 0.199999988079071044921875
cloud_color
- 0.09411763399839401245117188
- 0.1499999910593032836914063
- 0.199999988079071044921875
- 0.199999988079071044921875
+ 0.329999983310699462890625
+ 0.329999983310699462890625
+ 0.329999983310699462890625
+ 0.329999983310699462890625
cloud_pos_density1
0.5
0.5
- 0.07000000029802322387695313
+ 0.0999999940395355224609375
1
cloud_pos_density2
@@ -56,21 +56,21 @@
cloud_shadow
- 0.5
+ 0.39999997615814208984375
0
0
1
density_multiplier
- 0.0001999999949475750327110291
+ 4.999999873689375817775726e-05
0
0
1
distance_multiplier
- 8
+ 10
0
0
1
@@ -84,21 +84,21 @@
gamma
- 0.699999988079071044921875
+ 1
0
0
1
glow
- 11.6000003814697265625
+ 20
0.001000000047497451305389404
- -0.749999940395355224609375
+ -1.25
1
haze_density
- 0.5
+ 2
0
0
1
@@ -119,7 +119,7 @@
max_y
- 500
+ 4000
0
0
1
@@ -127,15 +127,15 @@
preset_num
10
star_brightness
- 0.3599999845027923583984375
+ 0.5
sun_angle
3.4557521343231201171875
sunlight_color
- 0.1499999910593032836914063
- 0.1499999910593032836914063
- 0.1499999910593032836914063
- 0.04999999701976776123046875
+ 0.08999999612569808959960938
+ 0.1799999922513961791992188
+ 0.2999999821186065673828125
+ 0.0999999940395355224609375
diff --git a/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Studio%201.xml b/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Studio%201.xml
new file mode 100644
index 000000000..b299d5c02
--- /dev/null
+++ b/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Studio%201.xml
@@ -0,0 +1,141 @@
+
+
+ ambient
+
+ 0.599999964237213134765625
+ 0.599999964237213134765625
+ 0.599999964237213134765625
+ 0.199999988079071044921875
+
+ blue_density
+
+ 2
+ 2
+ 2
+ 1
+
+ blue_horizon
+
+ 0.599999964237213134765625
+ 0.599999964237213134765625
+ 0.599999964237213134765625
+ 0.2999999821186065673828125
+
+ cloud_color
+
+ 0.2999999821186065673828125
+ 0.2999999821186065673828125
+ 0.2999999821186065673828125
+ 0.2999999821186065673828125
+
+ cloud_pos_density1
+
+ 1
+ 1
+ 0.25
+ 1
+
+ cloud_pos_density2
+
+ 1.6884100437164306640625
+ 1
+ 0
+ 1
+
+ cloud_scale
+
+ 0.07000000029802322387695313
+ 0
+ 0
+ 1
+
+ cloud_scroll_rate
+
+ 10.3999996185302734375
+ 10
+
+ cloud_shadow
+
+ 0.61000001430511474609375
+ 0
+ 0
+ 1
+
+ density_multiplier
+
+ 9.999999747378751635551453e-05
+ 0
+ 0
+ 1
+
+ distance_multiplier
+
+ 5
+ 0
+ 0
+ 1
+
+ east_angle
+ 1.06814157962799072265625
+ enable_cloud_scroll
+
+ 1
+ 1
+
+ gamma
+
+ 1
+ 0
+ 0
+ 1
+
+ glow
+
+ 0.200002193450927734375
+ 0.001000000047497451305389404
+ -0.199999988079071044921875
+ 1
+
+ haze_density
+
+ 4
+ 0
+ 0
+ 1
+
+ haze_horizon
+
+ 0.2099999934434890747070313
+ 0.1991560012102127075195313
+ 0.1991560012102127075195313
+ 1
+
+ lightnorm
+
+ 0.38304769992828369140625
+ 0.89940512180328369140625
+ -0.2105822265148162841796875
+ 0
+
+ max_y
+
+ 0
+ 0
+ 0
+ 1
+
+ preset_num
+ 22
+ star_brightness
+ 0
+ sun_angle
+ 2.0231859683990478515625
+ sunlight_color
+
+ 1.5
+ 1.5
+ 1.5
+ 0.5
+
+
+
diff --git a/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Studio%20Spotlight.xml b/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Studio%20Spotlight.xml
new file mode 100644
index 000000000..7e919afff
--- /dev/null
+++ b/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Studio%20Spotlight.xml
@@ -0,0 +1,141 @@
+
+
+ ambient
+
+ 0
+ 0
+ 0
+ 0
+
+ blue_density
+
+ 0
+ 0
+ 0
+ 0
+
+ blue_horizon
+
+ 0
+ 0
+ 0
+ 0
+
+ cloud_color
+
+ 0.2999999821186065673828125
+ 0.2999999821186065673828125
+ 0.2999999821186065673828125
+ 0.2999999821186065673828125
+
+ cloud_pos_density1
+
+ 1
+ 1
+ 0.25
+ 1
+
+ cloud_pos_density2
+
+ 1.6884100437164306640625
+ 1
+ 0
+ 1
+
+ cloud_scale
+
+ 0.07000000029802322387695313
+ 0
+ 0
+ 1
+
+ cloud_scroll_rate
+
+ 10.3999996185302734375
+ 10
+
+ cloud_shadow
+
+ 0
+ 0
+ 0
+ 1
+
+ density_multiplier
+
+ 0
+ 0
+ 0
+ 1
+
+ distance_multiplier
+
+ 100
+ 0
+ 0
+ 1
+
+ east_angle
+ 0
+ enable_cloud_scroll
+
+ 1
+ 1
+
+ gamma
+
+ 1
+ 0
+ 0
+ 1
+
+ glow
+
+ 0.200002193450927734375
+ 0.001000000047497451305389404
+ -0.199999988079071044921875
+ 1
+
+ haze_density
+
+ 1
+ 0
+ 0
+ 1
+
+ haze_horizon
+
+ 0.2099999934434890747070313
+ 0.1991560012102127075195313
+ 0.1991560012102127075195313
+ 1
+
+ lightnorm
+
+ 0
+ 0.587785184383392333984375
+ -0.80901706218719482421875
+ 0
+
+ max_y
+
+ 0
+ 0
+ 0
+ 1
+
+ preset_num
+ 22
+ star_brightness
+ 0
+ sun_angle
+ 2.51327419281005859375
+ sunlight_color
+
+ 2.009999752044677734375
+ 2.009999752044677734375
+ 2.009999752044677734375
+ 0.66999995708465576171875
+
+
+
diff --git a/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Sunrise.xml b/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Sunrise.xml
index 5276d856e..114564084 100644
--- a/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Sunrise.xml
+++ b/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Sunrise.xml
@@ -2,10 +2,10 @@
ambient
+ 0
0.449999988079071044921875
- 0.75
- 1.0499999523162841796875
- 0.3499999940395355224609375
+ 0.89999997615814208984375
+ 0.2999999821186065673828125
blue_density
@@ -23,16 +23,16 @@
cloud_color
- 0.199999988079071044921875
- 0.199999988079071044921875
- 0.199999988079071044921875
- 0.199999988079071044921875
+ 0.25
+ 0.25
+ 0.25
+ 0.25
cloud_pos_density1
1
1
- 0.25
+ 0.189999997615814208984375
1
cloud_pos_density2
@@ -44,7 +44,7 @@
cloud_scale
- 0.0999999940395355224609375
+ 0.07000000029802322387695313
0
0
1
@@ -91,21 +91,21 @@
glow
- 4.00000095367431640625
+ 38
0.001000000047497451305389404
- -0.39999997615814208984375
+ -0.2499999850988388061523438
1
haze_density
- 0.75
+ 0.199999988079071044921875
0
0
1
haze_horizon
- 0.199999988079071044921875
+ 0.5
0.1991560012102127075195313
0.1991560012102127075195313
1
@@ -132,10 +132,10 @@
0.31415927410125732421875
sunlight_color
- 3
+ 2.9999997615814208984375
1.19999992847442626953125
- 0.2999999821186065673828125
- 3
+ 0.449999988079071044921875
+ 1
diff --git a/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Sunset.xml b/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Sunset.xml
index 05556e43a..3fe84a505 100644
--- a/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Sunset.xml
+++ b/indra/newview/app_settings/windlight/skies/%5BPyFX%5D%20Sunset.xml
@@ -23,16 +23,16 @@
cloud_color
- 0.09999998658895492553710938
- 0.09999998658895492553710938
- 0.09999998658895492553710938
- 0.0999999940395355224609375
+ 0
+ 0.02999999932944774627685547
+ 0.05999999865889549255371094
+ 0.05999999865889549255371094
cloud_pos_density1
1
1
- 0.1499999910593032836914063
+ 0.1199999973177909851074219
1
cloud_pos_density2
@@ -44,7 +44,7 @@
cloud_scale
- 0.0999999940395355224609375
+ 0.07000000029802322387695313
0
0
1
diff --git a/indra/newview/app_settings/windlight/water/%5BPyFX%5D%20Ice.xml b/indra/newview/app_settings/windlight/water/%5BPyFX%5D%20Ice.xml
new file mode 100644
index 000000000..a5cdf76ae
--- /dev/null
+++ b/indra/newview/app_settings/windlight/water/%5BPyFX%5D%20Ice.xml
@@ -0,0 +1,43 @@
+
+
+ blurMultiplier
+ 0.1600000113248825073242188
+ fresnelOffset
+ 0.5
+ fresnelScale
+ 1
+ normScale
+
+ 5
+ 5
+ 5
+
+ normalMap
+ f92da839-f302-c813-668d-601ab1957af1
+ scaleAbove
+ 0.199999988079071044921875
+ scaleBelow
+ 0.2000000029802322387695313
+ underWaterFogMod
+ 1
+ waterFogColor
+
+ 0.02851562201976776123046875
+ 0.07148437201976776123046875
+ 0.06242064759135246276855469
+ 1
+
+ waterFogDensity
+ 2
+ wave1Dir
+
+ 0
+ 0
+
+ wave2Dir
+
+ 0
+ 0
+
+
+
diff --git a/indra/newview/app_settings/windlight/water/Py%27s%20Default%20%2B%20Texture.xml b/indra/newview/app_settings/windlight/water/Py%27s%20Default%20%2B%20Texture.xml
index 1129333af..b945a41d8 100644
--- a/indra/newview/app_settings/windlight/water/Py%27s%20Default%20%2B%20Texture.xml
+++ b/indra/newview/app_settings/windlight/water/Py%27s%20Default%20%2B%20Texture.xml
@@ -1,16 +1,16 @@
blurMultiplier
- 0.08000000566244125366210938
+ 0.01000000070780515670776367
fresnelOffset
- 0.550000011920928955078125
+ 0.5
fresnelScale
- 0.75
+ 0.5
normScale
- 5
- 5
- 5
+ 4
+ 4
+ 1
normalMap
7f132b94-6c9c-5af3-5a17-3412ad653da0
@@ -19,25 +19,25 @@
scaleBelow
0.2000000029802322387695313
underWaterFogMod
- 1
+ 0.66999995708465576171875
waterFogColor
- 0.02851562201976776123046875
- 0.07148437201976776123046875
- 0.06242064759135246276855469
+ 0.1960784494876861572265625
+ 0.2196078598499298095703125
+ 0.1764705926179885864257813
1
waterFogDensity
- 16
+ 103.96833038330078125
wave1Dir
- -0.1000001430511474609375
- -0.1000001430511474609375
+ -0.25
+ 0
wave2Dir
- -0.5
- -0.5
+ -1
+ 0
diff --git a/indra/newview/app_settings/windlight/water/Py%27s%20Default.xml b/indra/newview/app_settings/windlight/water/Py%27s%20Default.xml
index 4b3fa5a4f..1c443156c 100644
--- a/indra/newview/app_settings/windlight/water/Py%27s%20Default.xml
+++ b/indra/newview/app_settings/windlight/water/Py%27s%20Default.xml
@@ -1,43 +1,43 @@
blurMultiplier
- 0.010000000707805157
+ 0.04500000178813934326171875
fresnelOffset
0.5
fresnelScale
- 0.39999997615814209
+ 0.5
normScale
- 2
- 2
- 2
+ 1.10000002384185791015625
+ 1
+ 1
normalMap
822ded49-9a6c-f61c-cb89-6df54f42cdf4
scaleAbove
- 0.029999999329447746
+ 0.02999999932944774627685547
scaleBelow
- 0.099999994039535522
+ 0.2000000029802322387695313
underWaterFogMod
- 0.25
+ 0.66999995708465576171875
waterFogColor
- 0
- 0.039215687662363052
- 0.039215687662363052
+ 0.199999988079071044921875
+ 0.2199999988079071044921875
+ 0.1799999773502349853515625
1
waterFogDensity
- 32
+ 103.96833038330078125
wave1Dir
- 1.0499997138977051
- -0.42000007629394531
+ -1
+ 0
wave2Dir
- 1.1099996566772461
- -1.1600000858306885
+ -1
+ 0
diff --git a/indra/newview/app_settings/windlight/water/Py%27s%20Ocean%20%2B%20Texture.xml b/indra/newview/app_settings/windlight/water/Py%27s%20Ocean%20%2B%20Texture.xml
new file mode 100644
index 000000000..edd3e9a97
--- /dev/null
+++ b/indra/newview/app_settings/windlight/water/Py%27s%20Ocean%20%2B%20Texture.xml
@@ -0,0 +1,43 @@
+
+
+ blurMultiplier
+ 0.05000000074505805969238281
+ fresnelOffset
+ 0.5
+ fresnelScale
+ 0.5
+ normScale
+
+ 5
+ 5
+ 5
+
+ normalMap
+ 7f132b94-6c9c-5af3-5a17-3412ad653da0
+ scaleAbove
+ 0.04999999701976776123046875
+ scaleBelow
+ 0.2000000029802322387695313
+ underWaterFogMod
+ 1
+ waterFogColor
+
+ 0.194549560546875
+ 0.602325439453125
+ 0.50675296783447265625
+ 1
+
+ waterFogDensity
+ 8
+ wave1Dir
+
+ -0.1000001430511474609375
+ -0.1000001430511474609375
+
+ wave2Dir
+
+ -0.5
+ -0.5
+
+
+
diff --git a/indra/newview/app_settings/windlight/water/Py%27s%20Ocean%202%20%2B%20Texture.xml b/indra/newview/app_settings/windlight/water/Py%27s%20Ocean%202%20%2B%20Texture.xml
new file mode 100644
index 000000000..5eaa00845
--- /dev/null
+++ b/indra/newview/app_settings/windlight/water/Py%27s%20Ocean%202%20%2B%20Texture.xml
@@ -0,0 +1,43 @@
+
+
+ blurMultiplier
+ 0.005000000353902578353881836
+ fresnelOffset
+ 0.599999964237213134765625
+ fresnelScale
+ 0.2999999821186065673828125
+ normScale
+
+ 1
+ 1
+ 1
+
+ normalMap
+ 7f132b94-6c9c-5af3-5a17-3412ad653da0
+ scaleAbove
+ 0.02999999932944774627685547
+ scaleBelow
+ 0.2000000029802322387695313
+ underWaterFogMod
+ 0.5
+ waterFogColor
+
+ 0.1882353127002716064453125
+ 0.2509804069995880126953125
+ 0.3137255012989044189453125
+ 1
+
+ waterFogDensity
+ 32
+ wave1Dir
+
+ -0.5
+ 0
+
+ wave2Dir
+
+ -2
+ 0
+
+
+
diff --git a/indra/newview/app_settings/windlight/water/Py%27s%20Ocean%202.xml b/indra/newview/app_settings/windlight/water/Py%27s%20Ocean%202.xml
new file mode 100644
index 000000000..6866eacad
--- /dev/null
+++ b/indra/newview/app_settings/windlight/water/Py%27s%20Ocean%202.xml
@@ -0,0 +1,43 @@
+
+
+ blurMultiplier
+ 0.04500000178813934326171875
+ fresnelOffset
+ 0.599999964237213134765625
+ fresnelScale
+ 0.2999999821186065673828125
+ normScale
+
+ 1
+ 1
+ 1
+
+ normalMap
+ 822ded49-9a6c-f61c-cb89-6df54f42cdf4
+ scaleAbove
+ 0.02999999932944774627685547
+ scaleBelow
+ 0.2000000029802322387695313
+ underWaterFogMod
+ 0.5
+ waterFogColor
+
+ 0.1882353127002716064453125
+ 0.2509804069995880126953125
+ 0.3137255012989044189453125
+ 1
+
+ waterFogDensity
+ 32
+ wave1Dir
+
+ -2
+ 0
+
+ wave2Dir
+
+ -4
+ 0
+
+
+
diff --git a/indra/newview/ascentprefssys.cpp b/indra/newview/ascentprefssys.cpp
index a2c577d0d..5c8ddc9e9 100644
--- a/indra/newview/ascentprefssys.cpp
+++ b/indra/newview/ascentprefssys.cpp
@@ -77,7 +77,6 @@ LLPrefsAscentSys::LLPrefsAscentSys()
getChild("AlchemyChatCommandHoverHeight")->setCommitCallback(lineEditorControl);
//Security ----------------------------------------------------------------------------
- getChild("UISndRestart")->setCommitCallback(lineEditorControl);
//Build -------------------------------------------------------------------------------
getChild("next_owner_copy")->setCommitCallback(boost::bind(&LLPrefsAscentSys::onCommitCheckBox, this, _1, _2));
@@ -207,8 +206,7 @@ void LLPrefsAscentSys::refreshValues()
mDisableClickSitOtherOwner = gSavedSettings.getBOOL("DisableClickSitOtherOwner");
mDisplayScriptJumps = gSavedSettings.getBOOL("AscentDisplayTotalScriptJumps");
mNumScriptDiff = gSavedSettings.getF32("Ascentnumscriptdiff");
- mRestartMinimized = gSavedSettings.getBOOL("LiruRegionRestartMinimized");
- mRestartSound = gSavedSettings.getString("UISndRestart");
+ mReplaceLinks = gSavedSettings.getBOOL("SinguReplaceLinks");
mLandmark = gSavedPerAccountSettings.getString("EmergencyTeleportLandmark");
mLandmarkBackup = gSavedPerAccountSettings.getString("EmergencyTeleportLandmarkBackup");
@@ -266,8 +264,6 @@ void LLPrefsAscentSys::refresh()
childSetValue("AlchemyChatCommandHoverHeight", mCmdLineHover);
//Security ----------------------------------------------------------------------------
- getChildView("UISndRestart")->setValue(mRestartSound);
-
if (LLComboBox* combo = getChild("lookat_namesystem_combobox"))
combo->setValue(mLookAtNames);
@@ -356,8 +352,7 @@ void LLPrefsAscentSys::cancel()
gSavedSettings.setBOOL("DisableClickSitOtherOwner", mDisableClickSitOtherOwner);
gSavedSettings.setBOOL("AscentDisplayTotalScriptJumps", mDisplayScriptJumps);
gSavedSettings.setF32("Ascentnumscriptdiff", mNumScriptDiff);
- gSavedSettings.setBOOL("LiruRegionRestartMinimized", mRestartMinimized);
- gSavedSettings.setString("UISndRestart", mRestartSound);
+ gSavedSettings.setBOOL("SinguReplaceLinks", mReplaceLinks);
gSavedPerAccountSettings.setString("EmergencyTeleportLandmark", mLandmark);
gSavedPerAccountSettings.setString("EmergencyTeleportLandmarkBackup", mLandmarkBackup);
diff --git a/indra/newview/ascentprefssys.h b/indra/newview/ascentprefssys.h
index ae7a07cab..187212b38 100644
--- a/indra/newview/ascentprefssys.h
+++ b/indra/newview/ascentprefssys.h
@@ -116,9 +116,8 @@ private:
bool mDisableClickSit;
bool mDisableClickSitOtherOwner;
bool mDisplayScriptJumps;
- bool mRestartMinimized;
+ bool mReplaceLinks;
F32 mNumScriptDiff;
- std::string mRestartSound;
std::string mLandmark;
std::string mLandmarkBackup;
diff --git a/indra/newview/ascentprefsvan.cpp b/indra/newview/ascentprefsvan.cpp
index 6a51b580f..0c6216647 100644
--- a/indra/newview/ascentprefsvan.cpp
+++ b/indra/newview/ascentprefsvan.cpp
@@ -62,6 +62,8 @@ LLPrefsAscentVan::LLPrefsAscentVan()
getChild("tag_spoofing_combobox")->setCommitCallback(boost::bind(&LLPrefsAscentVan::onCommitClientTag, this, _1));
getChild("custom_tag_label_box")->setCommitCallback(boost::bind(&LLControlGroup::setString, boost::ref(gSavedSettings), "AscentCustomTagLabel", _2));
+ commit_callback_t lineEditorControl(boost::bind(&LLControlGroup::setString, boost::ref(gSavedSettings), boost::bind(&LLUICtrl::getName, _1), _2));
+ getChild("UISndRestart")->setCommitCallback(lineEditorControl);
getChild("update_clientdefs")->setCommitCallback(boost::bind(LLPrefsAscentVan::onManualClientUpdate));
@@ -126,10 +128,13 @@ void LLPrefsAscentVan::refreshValues()
mCustomizeAnim = gSavedSettings.getBOOL("LiruCustomizeAnim");
mAnnounceSnapshots = gSavedSettings.getBOOL("AnnounceSnapshots");
mAnnounceStreamMetadata = gSavedSettings.getBOOL("AnnounceStreamMetadata");
- mUnfocusedFloatersOpaque = gSavedSettings.getBOOL("FloaterUnfocusedBackgroundOpaque");
+ mInactiveFloaterTransparency = gSavedSettings.getF32("InactiveFloaterTransparency");
+ mActiveFloaterTransparency = gSavedSettings.getF32("ActiveFloaterTransparency");
mCompleteNameProfiles = gSavedSettings.getBOOL("SinguCompleteNameProfiles");
mScriptErrorsStealFocus = gSavedSettings.getBOOL("LiruScriptErrorsStealFocus");
mConnectToNeighbors = gSavedSettings.getBOOL("AlchemyConnectToNeighbors");
+ mRestartMinimized = gSavedSettings.getBOOL("LiruRegionRestartMinimized");
+ mRestartSound = gSavedSettings.getString("UISndRestart");
//Tags\Colors ----------------------------------------------------------------------------
mAscentBroadcastTag = gSavedSettings.getBOOL("AscentBroadcastTag");
@@ -169,6 +174,7 @@ void LLPrefsAscentVan::refreshValues()
void LLPrefsAscentVan::refresh()
{
//Main -----------------------------------------------------------------------------------
+ getChildView("UISndRestart")->setValue(mRestartSound);
//Tags\Colors ----------------------------------------------------------------------------
LLComboBox* combo = getChild("tag_spoofing_combobox");
@@ -197,10 +203,13 @@ void LLPrefsAscentVan::cancel()
gSavedSettings.setBOOL("LiruCustomizeAnim", mCustomizeAnim);
gSavedSettings.setBOOL("AnnounceSnapshots", mAnnounceSnapshots);
gSavedSettings.setBOOL("AnnounceStreamMetadata", mAnnounceStreamMetadata);
- gSavedSettings.setBOOL("FloaterUnfocusedBackgroundOpaque", mUnfocusedFloatersOpaque);
+ gSavedSettings.setF32("InactiveFloaterTransparency", mInactiveFloaterTransparency);
+ gSavedSettings.setF32("ActiveFloaterTransparency", mActiveFloaterTransparency);
gSavedSettings.setBOOL("SinguCompleteNameProfiles", mCompleteNameProfiles);
gSavedSettings.setBOOL("LiruScriptErrorsStealFocus", mScriptErrorsStealFocus);
gSavedSettings.setBOOL("AlchemyConnectToNeighbors", mConnectToNeighbors);
+ gSavedSettings.setBOOL("LiruRegionRestartMinimized", mRestartMinimized);
+ gSavedSettings.setString("UISndRestart", mRestartSound);
//Tags\Colors ----------------------------------------------------------------------------
gSavedSettings.setBOOL("AscentBroadcastTag", mAscentBroadcastTag);
diff --git a/indra/newview/ascentprefsvan.h b/indra/newview/ascentprefsvan.h
index b45adf652..d8e27338e 100644
--- a/indra/newview/ascentprefsvan.h
+++ b/indra/newview/ascentprefsvan.h
@@ -62,10 +62,12 @@ private:
bool mCustomizeAnim;
bool mAnnounceSnapshots;
bool mAnnounceStreamMetadata;
- bool mUnfocusedFloatersOpaque;
+ F32 mInactiveFloaterTransparency, mActiveFloaterTransparency;
bool mCompleteNameProfiles;
bool mScriptErrorsStealFocus;
bool mConnectToNeighbors;
+ bool mRestartMinimized;
+ std::string mRestartSound;
//Tags\Colors
bool mAscentBroadcastTag;
std::string mReportClientUUID;
diff --git a/indra/newview/chatbar_as_cmdline.cpp b/indra/newview/chatbar_as_cmdline.cpp
index c03d8424c..2863cfe92 100644
--- a/indra/newview/chatbar_as_cmdline.cpp
+++ b/indra/newview/chatbar_as_cmdline.cpp
@@ -42,6 +42,7 @@
#include "llagentui.h"
#include "llavataractions.h"
#include "llnotificationsutil.h"
+#include "llsdserialize.h"
#include "llviewerregion.h"
#include "llworld.h"
#include "lleventtimer.h"
@@ -242,11 +243,11 @@ bool cmd_line_chat(std::string data, EChatType type)
static LLCachedControl enableChatCmd(gSavedSettings, "AscentCmdLine", true);
if (enableChatCmd)
{
- data = utf8str_tolower(data);
std::istringstream input(data);
std::string cmd;
if (!(input >> cmd)) return true;
+ cmd = utf8str_tolower(cmd);
static LLCachedControl sDrawDistanceCommand(gSavedSettings, "AscentCmdLineDrawDistance");
static LLCachedControl sHeightCommand(gSavedSettings, "AscentCmdLineHeight");
@@ -266,6 +267,7 @@ bool cmd_line_chat(std::string data, EChatType type)
static LLCachedControl sTP2Command(gSavedSettings, "AscentCmdLineTP2");
static LLCachedControl sAwayCommand(gSavedSettings, "SinguCmdLineAway");
static LLCachedControl sURLCommand(gSavedSettings, "SinguCmdLineURL");
+ static LLCachedControl sSettingCommand(gSavedSettings, "SinguCmdLineSetting");
if (cmd == utf8str_tolower(sDrawDistanceCommand)) // dd
{
@@ -396,7 +398,7 @@ bool cmd_line_chat(std::string data, EChatType type)
slurl = LLSLURL(slurl.getRegion(), LLVector3(fmod(agentPos.mdV[VX], (F64)REGION_WIDTH_METERS), fmod(agentPos.mdV[VY], (F64)REGION_WIDTH_METERS), agentPos.mdV[VZ]));
}
- LLUrlAction::teleportToLocation(LLWeb::escapeURL(std::string("secondlife:///app/teleport/")+slurl.getLocationString()));
+ LLUrlAction::teleportToLocation(LLWeb::escapeURL("secondlife:///app/teleport/"+slurl.getLocationString()));
}
return false;
}
@@ -535,7 +537,55 @@ bool cmd_line_chat(std::string data, EChatType type)
LLAvatarActions::showProfile(id);
return false;
}
- LLUrlAction::clickAction(sub);
+ LLUrlAction::clickAction(sub, true);
+ }
+ return false;
+ }
+ else if (cmd == utf8str_tolower(sSettingCommand))
+ {
+ std::string control_name;
+ if (input >> control_name)
+ {
+ // Find out if this control even exists.
+ auto control = gSavedSettings.getControl(control_name);
+ if (!control) gSavedPerAccountSettings.getControl(control_name);
+ if (!control) return false;
+
+ LLSD val;
+ // Toggle if we weren't given a value,
+ if (input.eof()) val = !control->get();
+ else // otherwise use what we were given.
+ {
+ switch (control->type()) // Convert to the right type, we can't be a string forever.
+ {
+ case TYPE_U32: // Integer is Integer, sucks but whatever
+ case TYPE_S32:
+ {
+ LLSD::Integer i;
+ input >> i;
+ val = i;
+ break;
+ }
+ case TYPE_F32:
+ {
+ LLSD::Float f;
+ input >> f;
+ val = f;
+ break;
+ }
+ case TYPE_STRING:
+ {
+ LLSD::String str;
+ std::getline(input, str, '\0'); // Read the entire rest of the stream into str
+ LLStringUtil::trim(str); // There's no setting where a space would be necessary here.
+ val = str;
+ break;
+ }
+ default: // Just parse it like JSON (or accept one of the many boolean value options!
+ LLSDSerialize::fromNotation(val, input, LLSDSerialize::SIZE_UNLIMITED);
+ }
+ }
+ control->set(val);
}
return false;
}
@@ -586,10 +636,10 @@ LLUUID cmdline_partial_name2key(std::string partial_name)
std::string av_name;
LLStringUtil::toLower(partial_name);
LLWorld::getInstance()->getAvatars(&avatars);
- auto instance = (LLFloaterAvatarList::instanceExists() ? &LLFloaterAvatarList::instance() : nullptr);
+ auto radar = (LLFloaterAvatarList::instanceExists() ? LLFloaterAvatarList::getInstance() : nullptr);
for(const auto& id : avatars)
{
- if (LLAvatarListEntry* entry = instance ? instance->getAvatarEntry(id) : nullptr)
+ if (LLAvatarListEntry* entry = radar ? radar->getAvatarEntry(id) : nullptr)
av_name = entry->getName();
else if (gCacheName->getFullName(id, av_name));
else if (LLVOAvatar* avatarp = gObjectList.findAvatar(id))
diff --git a/indra/newview/floaterao.cpp b/indra/newview/floaterao.cpp
index 0d584e6e5..2038aaa13 100644
--- a/indra/newview/floaterao.cpp
+++ b/indra/newview/floaterao.cpp
@@ -16,13 +16,8 @@
#include "llstartup.h"
#include "llpreviewnotecard.h"
#include "llviewertexteditor.h"
-#include "llcheckboxctrl.h"
#include "llcombobox.h"
-#include "llspinctrl.h"
-#include "chatbar_as_cmdline.h"
-//#include "llfloaterchat.h"
#include "llfirstuse.h"
-#include "lltrans.h"
#include "llinventory.h"
#include "llinventoryfunctions.h"
@@ -31,15 +26,24 @@
#include "roles_constants.h"
#include "llviewerregion.h"
-#include "llpanelobjectinventory.h"
#include "llinventorybridge.h"
-#include "llboost.h"
#include
// Uncomment and use instead if we ever add the chatbar as a command line - MC
void cmdline_printchat(const std::string& message);
+namespace
+{
+ bool sSwimming = false;
+ bool enable_swim()
+ {
+ static const LLCachedControl swim(gSavedSettings, "AOSwimEnabled", false);
+ return swim;
+ }
+ bool is_underwater() { return enable_swim() && gAgentAvatarp && gAgentAvatarp->mBelowWater; }
+}
+
class AONotecardCallback : public LLInventoryCallback
{
public:
@@ -52,28 +56,32 @@ public:
{
if (!mFileName.empty())
{
- LLPreviewNotecard* nc;
- nc = (LLPreviewNotecard*)LLPreview::find(inv_item);
- if(nc)
+ LLPreviewNotecard* nc = (LLPreviewNotecard*)LLPreview::show(inv_item);
+ if (!nc)
{
- nc->open();
- LLTextEditor *text = nc->getEditor();
- if (text)
+ auto item = gInventory.getItem(inv_item);
+ open_notecard(item, "Note: " + item->getName(), LLUUID::null, false);
+ nc = (LLPreviewNotecard*)LLPreview::find(inv_item);
+ }
+
+ if (nc)
+ {
+ if (LLTextEditor *text = nc->getEditor())
{
text->clear();
text->makePristine();
std::ifstream file(mFileName.c_str());
-
+
std::string line;
while (!file.eof())
- {
+ {
getline(file, line);
- line = line + "\n";
+ line += '\n';
text->insertText(line);
}
file.close();
-
+
nc->saveIfNeeded();
}
}
@@ -84,7 +92,7 @@ private:
std::string mFileName;
};
-AOInvTimer* gAOInvTimer = NULL;
+AOInvTimer* gAOInvTimer = nullptr;
// -------------------------------------------------------
@@ -93,7 +101,7 @@ AOStandTimer* mAOStandTimer;
AOStandTimer::AOStandTimer() : LLEventTimer( gSavedSettings.getF32("AOStandInterval") )
{
- AOStandTimer::tick();
+ tick();
}
AOStandTimer::~AOStandTimer()
{
@@ -110,13 +118,13 @@ BOOL AOStandTimer::tick()
LLFloaterAO::stand_iterator++;
// LL_INFOS() << "tick" << LL_ENDL;
LLFloaterAO::ChangeStand();
- return FALSE;
+ return false;
// return LLFloaterAO::ChangeStand(); //timer is always active now ..
}
// -------------------------------------------------------
-AOInvTimer::AOInvTimer() : LLEventTimer( (F32)1.0 )
+AOInvTimer::AOInvTimer() : LLEventTimer( 1.0f )
{
}
AOInvTimer::~AOInvTimer()
@@ -124,22 +132,21 @@ AOInvTimer::~AOInvTimer()
}
BOOL AOInvTimer::tick()
{
- if (!(gSavedSettings.getBOOL("AOEnabled"))) return TRUE;
if(LLStartUp::getStartupState() >= STATE_INVENTORY_SEND)
{
if(LLInventoryModelBackgroundFetch::instance().isEverythingFetched())
{
// cmdline_printchat("Inventory fetched, loading AO.");
- LLFloaterAO::init();
- return TRUE;
+ LLFloaterAO::getInstance(); // Initializes everything
+ return true;
}
}
- return FALSE;
+ return !gSavedSettings.getBOOL("AOEnabled");
}
// STUFF -------------------------------------------------------
-int LLFloaterAO::mAnimationState = 0;
+AOState LLFloaterAO::mAnimationState = STATE_AGENT_IDLE;
int LLFloaterAO::stand_iterator = 0;
LLUUID LLFloaterAO::invfolderid = LLUUID::null;
@@ -160,14 +167,19 @@ LLComboBox* mcomboBox_flyslows;
LLComboBox* mcomboBox_flyups;
LLComboBox* mcomboBox_flydowns;
LLComboBox* mcomboBox_lands;
+LLComboBox* mcomboBox_typings;
+LLComboBox* mcomboBox_floats;
+LLComboBox* mcomboBox_swims;
+LLComboBox* mcomboBox_swimups;
+LLComboBox* mcomboBox_swimdowns;
LLComboBox* mcomboBox_standups;
LLComboBox* mcomboBox_prejumps;
struct struct_overrides
{
LLUUID orig_id;
- LLUUID ao_id;
- int state;
+ LLUUID ao_id = LLUUID::null;
+ AOState state;
};
std::vector mAOOverrides;
@@ -178,139 +190,101 @@ struct struct_stands
};
std::vector mAOStands;
-struct struct_tokens
+LLFloaterAO::LLFloaterAO(const LLSD&) : LLFloater("floater_ao")
{
- std::string token;
- int state;
-};
-std::vector mAOTokens;
+ LLUICtrlFactory::getInstance()->buildFloater(this, "floater_ao.xml", nullptr, false);
+ init();
+ gSavedSettings.getControl("AOEnabled")->getSignal()->connect(boost::bind(&LLFloaterAO::run));
+ gSavedSettings.getControl("AOEnabled")->getSignal()->connect(std::bind([](const LLSD& enabled)
+ {
+ // Toggle typing AO the moment we toggle AO
+ const bool typing = gAgent.getRenderState() & AGENT_STATE_TYPING;
+ gAgent.sendAnimationRequest(GetAnimIDFromState(STATE_AGENT_TYPING), enabled && typing ? ANIM_REQUEST_START : ANIM_REQUEST_STOP);
+ }, std::placeholders::_2));
+ gSavedSettings.getControl("AOSitsEnabled")->getSignal()->connect(boost::bind(&LLFloaterAO::run));
+ sSwimming = is_underwater();
+ gSavedSettings.getControl("AOSwimEnabled")->getSignal()->connect(boost::bind(&LLFloaterAO::toggleSwim, boost::bind(is_underwater)));
+}
-LLFloaterAO* LLFloaterAO::sInstance = NULL;
-
-LLFloaterAO::LLFloaterAO()
-:LLFloater(std::string("floater_ao"))
+void LLFloaterAO::onOpen()
{
-// init();
- llassert_always(sInstance == NULL);
- LLUICtrlFactory::getInstance()->buildFloater(this, "floater_ao.xml");
- sInstance = this;
+ LLFirstUse::useAO();
}
LLFloaterAO::~LLFloaterAO()
{
- sInstance=NULL;
- mcomboBox_stands = 0;
- mcomboBox_walks = 0;
- mcomboBox_runs = 0;
- mcomboBox_jumps = 0;
- mcomboBox_sits = 0;
- mcomboBox_gsits = 0;
- mcomboBox_crouchs = 0;
- mcomboBox_cwalks = 0;
- mcomboBox_falls = 0;
- mcomboBox_hovers = 0;
- mcomboBox_flys = 0;
- mcomboBox_flyslows = 0;
- mcomboBox_flyups = 0;
- mcomboBox_flydowns = 0;
- mcomboBox_lands = 0;
- mcomboBox_standups = 0;
- mcomboBox_prejumps = 0;
+ mcomboBox_stands = nullptr;
+ mcomboBox_walks = nullptr;
+ mcomboBox_runs = nullptr;
+ mcomboBox_jumps = nullptr;
+ mcomboBox_sits = nullptr;
+ mcomboBox_gsits = nullptr;
+ mcomboBox_crouchs = nullptr;
+ mcomboBox_cwalks = nullptr;
+ mcomboBox_falls = nullptr;
+ mcomboBox_hovers = nullptr;
+ mcomboBox_flys = nullptr;
+ mcomboBox_flyslows = nullptr;
+ mcomboBox_flyups = nullptr;
+ mcomboBox_flydowns = nullptr;
+ mcomboBox_lands = nullptr;
+ mcomboBox_typings = nullptr;
+ mcomboBox_floats = nullptr;
+ mcomboBox_swims = nullptr;
+ mcomboBox_swimups = nullptr;
+ mcomboBox_swimdowns = nullptr;
+ mcomboBox_standups = nullptr;
+ mcomboBox_prejumps = nullptr;
// LL_INFOS() << "floater destroyed" << LL_ENDL;
}
-void LLFloaterAO::show(void*)
-{
- if (!sInstance)
- {
- sInstance = new LLFloaterAO();
- updateLayout(sInstance);
- init();
-
- sInstance->open();
- }
- else
- {
- sInstance->close();
- }
- LLFirstUse::useAO();
-}
-
-bool LLFloaterAO::getInstance()
-{
- if (sInstance)
- return true;
- else
- return false;
-}
-
BOOL LLFloaterAO::postBuild()
{
- childSetAction("more_btn", onClickMore, this);
- childSetAction("less_btn", onClickLess, this);
+ gSavedSettings.getControl("AOAdvanced")->getSignal()->connect(boost::bind(&LLFloaterAO::updateLayout, this, _2));
- childSetAction("reloadcard",onClickReloadCard,this);
- childSetAction("opencard",onClickOpenCard,this);
- childSetAction("newcard",onClickNewCard,this);
- childSetAction("prevstand",onClickPrevStand,this);
- childSetAction("nextstand",onClickNextStand,this);
- getChild("AOEnabled")->setCommitCallback(boost::bind(&LLFloaterAO::onClickToggleAO));
- getChild("AOSitsEnabled")->setCommitCallback(boost::bind(&LLFloaterAO::onClickToggleSits));
- getChild("standtime")->setCommitCallback(boost::bind(&LLFloaterAO::onSpinnerCommit,_1));
- mcomboBox_stands = getChild("stands");
- mcomboBox_walks = getChild("walks");
- mcomboBox_runs = getChild("runs");
- mcomboBox_jumps = getChild("jumps");
- mcomboBox_sits = getChild("sits");
- mcomboBox_gsits = getChild("gsits");
- mcomboBox_crouchs = getChild("crouchs");
- mcomboBox_cwalks = getChild("cwalks");
- mcomboBox_falls = getChild("falls");
- mcomboBox_hovers = getChild("hovers");
- mcomboBox_flys = getChild("flys");
- mcomboBox_flyslows = getChild("flyslows");
- mcomboBox_flyups = getChild("flyups");
- mcomboBox_flydowns = getChild("flydowns");
- mcomboBox_lands = getChild("lands");
- mcomboBox_standups = getChild("standups");
- mcomboBox_prejumps = getChild("prejumps");
- getChild("stands")->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit,_1));
- getChild("walks")->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit,_1));
- getChild("runs")->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit,_1));
- getChild("jumps")->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit,_1));
- getChild("sits")->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit,_1));
- getChild("gsits")->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit,_1));
- getChild("crouchs")->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit,_1));
- getChild("cwalks")->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit,_1));
- getChild("falls")->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit,_1));
- getChild("hovers")->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit,_1));
- getChild("flys")->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit,_1));
- getChild("flyslows")->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit,_1));
- getChild("flyups")->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit,_1));
- getChild("flydowns")->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit,_1));
- getChild("lands")->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit,_1));
- getChild("standups")->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit,_1));
- getChild("prejumps")->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit,_1));
+ getChild("reloadcard")->setCommitCallback(boost::bind(&LLFloaterAO::onClickReloadCard));
+ getChild("opencard")->setCommitCallback(boost::bind(&LLFloaterAO::onClickOpenCard));
+ getChild("newcard")->setCommitCallback(boost::bind(&LLFloaterAO::onClickNewCard));
+ getChild("prevstand")->setCommitCallback(boost::bind(&LLFloaterAO::onClickCycleStand, false));
+ getChild("nextstand")->setCommitCallback(boost::bind(&LLFloaterAO::onClickCycleStand, true));
+ getChild("standtime")->setCommitCallback(boost::bind(&LLFloaterAO::onSpinnerCommit));
- return TRUE;
+ (mcomboBox_stands = getChild("stands"))->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit,_1));
+ (mcomboBox_walks = getChild("walks"))->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit,_1));
+ (mcomboBox_runs = getChild("runs"))->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit,_1));
+ (mcomboBox_jumps = getChild("jumps"))->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit,_1));
+ (mcomboBox_sits = getChild("sits"))->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit,_1));
+ (mcomboBox_gsits = getChild("gsits"))->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit,_1));
+ (mcomboBox_crouchs = getChild("crouchs"))->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit,_1));
+ (mcomboBox_cwalks = getChild("cwalks"))->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit,_1));
+ (mcomboBox_falls = getChild("falls"))->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit, _1));
+ (mcomboBox_hovers = getChild("hovers"))->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit, _1));
+ (mcomboBox_flys = getChild("flys"))->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit, _1));
+ (mcomboBox_flyslows = getChild("flyslows"))->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit, _1));
+ (mcomboBox_flyups = getChild("flyups"))->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit, _1));
+ (mcomboBox_flydowns = getChild("flydowns"))->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit, _1));
+ (mcomboBox_lands = getChild("lands"))->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit, _1));
+ (mcomboBox_typings = getChild("typings"))->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit, _1));
+ (mcomboBox_floats = getChild("floats"))->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit, _1));
+ (mcomboBox_swims = getChild("swims"))->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit, _1));
+ (mcomboBox_swimups = getChild("swimups"))->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit, _1));
+ (mcomboBox_swimdowns = getChild("swimdowns"))->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit, _1));
+ (mcomboBox_standups = getChild("standups"))->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit,_1));
+ (mcomboBox_prejumps = getChild("prejumps"))->setCommitCallback(boost::bind(&LLFloaterAO::onComboBoxCommit,_1));
+
+ updateLayout(gSavedSettings.getBOOL("AOAdvanced"));
+
+ return true;
}
-void LLFloaterAO::onSpinnerCommit(LLUICtrl* ctrl)
+void LLFloaterAO::onSpinnerCommit()
{
- LLSpinCtrl* spin = (LLSpinCtrl*) ctrl;
- if(spin)
- {
- if (spin->getName() == "standtime")
- {
- if (mAOStandTimer) mAOStandTimer->reset();
- }
- }
+ if (mAOStandTimer) mAOStandTimer->reset();
}
void LLFloaterAO::onComboBoxCommit(LLUICtrl* ctrl)
{
- LLComboBox* box = (LLComboBox*)ctrl;
- if(box)
+ if (LLComboBox* box = (LLComboBox*)ctrl)
{
if (box->getName() == "stands")
{
@@ -320,250 +294,81 @@ void LLFloaterAO::onComboBoxCommit(LLUICtrl* ctrl)
}
else
{
- int state = STATE_AGENT_IDLE;
+ AOState state = getStateFromCombo(box);
std::string stranim = box->getValue().asString();
-// LL_INFOS() << "state " << (gAgentAvatarp->isSitting()) << " - " << getAnimationState() << LL_ENDL;
- if (box->getName() == "walks")
+// LL_INFOS() << "state " << state << " - " << getAnimationState() << LL_ENDL;
+ gAgent.sendAnimationRequest(GetAnimIDFromState(state), ANIM_REQUEST_STOP);
+ bool start_cond = getAnimationState() == state && gSavedSettings.getBOOL("AOEnabled");
+ switch (state)
{
- gAgent.sendAnimationRequest(GetAnimID(ANIM_AGENT_WALK), ANIM_REQUEST_STOP);
- gSavedPerAccountSettings.setString("AODefaultWalk",stranim);
- state = STATE_AGENT_WALK;
+ case STATE_AGENT_SIT:
+ case STATE_AGENT_GROUNDSIT:
+ start_cond &= gAgentAvatarp && gAgentAvatarp->isSitting() && gSavedSettings.getBOOL("AOSitsEnabled");
+ break;
+ default: break;
}
- else if (box->getName() == "runs")
+ LLUUID anim = getAssetIDByName(stranim);
+ if (start_cond) gAgent.sendAnimationRequest(anim, ANIM_REQUEST_START);
+ gSavedPerAccountSettings.setString(ctrl->getControlName(), stranim);
+ for (auto& ao : mAOOverrides)
{
- gAgent.sendAnimationRequest(GetAnimID(ANIM_AGENT_RUN), ANIM_REQUEST_STOP);
- gSavedPerAccountSettings.setString("AODefaultRun",stranim);
- state = STATE_AGENT_RUN;
- }
- else if (box->getName() == "jumps")
- {
- gAgent.sendAnimationRequest(GetAnimID(ANIM_AGENT_JUMP), ANIM_REQUEST_STOP);
- gSavedPerAccountSettings.setString("AODefaultJump",stranim);
- state = STATE_AGENT_JUMP;
- }
- else if (box->getName() == "sits")
- {
- if (gAgentAvatarp && (gSavedSettings.getBOOL("AOEnabled")) && (gSavedSettings.getBOOL("AOSitsEnabled")))
+ if (state == ao.state)
{
- if ((gAgentAvatarp->isSitting()) && (getAnimationState() == STATE_AGENT_SIT))
- {
-// LL_INFOS() << "sitting " << GetAnimID(ANIM_AGENT_SIT) << " " << getAssetIDByName(stranim) << LL_ENDL;
- gAgent.sendAnimationRequest(GetAnimID(ANIM_AGENT_SIT), ANIM_REQUEST_STOP);
- gAgent.sendAnimationRequest(getAssetIDByName(stranim), ANIM_REQUEST_START);
- }
- }
- gSavedPerAccountSettings.setString("AODefaultSit",stranim);
- state = STATE_AGENT_SIT;
- }
- else if (box->getName() == "gsits")
- {
-// LL_INFOS() << "gsitting " << GetAnimID(ANIM_AGENT_SIT_GROUND) << " " << getAssetIDByName(stranim) << LL_ENDL;
- if (gAgentAvatarp)
- {
- if ((gAgentAvatarp->isSitting()) && (getAnimationState() == STATE_AGENT_GROUNDSIT))
- {
-// LL_INFOS() << "gsitting " << GetAnimID(ANIM_AGENT_SIT_GROUND) << " " << getAssetIDByName(stranim) << LL_ENDL;
- gAgent.sendAnimationRequest(GetAnimID(ANIM_AGENT_SIT_GROUND), ANIM_REQUEST_STOP);
- gAgent.sendAnimationRequest(getAssetIDByName(stranim), ANIM_REQUEST_START);
- }
- }
- gSavedPerAccountSettings.setString("AODefaultGroundSit",stranim);
- state = STATE_AGENT_GROUNDSIT;
- }
- else if (box->getName() == "crouchs")
- {
- gAgent.sendAnimationRequest(GetAnimID(ANIM_AGENT_CROUCH), ANIM_REQUEST_STOP);
- gSavedPerAccountSettings.setString("AODefaultCrouch",stranim);
- state = STATE_AGENT_CROUCH;
- }
- else if (box->getName() == "cwalks")
- {
- gAgent.sendAnimationRequest(GetAnimID(ANIM_AGENT_CROUCHWALK), ANIM_REQUEST_STOP);
- gSavedPerAccountSettings.setString("AODefaultCrouchWalk",stranim);
- state = STATE_AGENT_CROUCHWALK;
- }
- else if (box->getName() == "falls")
- {
- gAgent.sendAnimationRequest(GetAnimID(ANIM_AGENT_FALLDOWN), ANIM_REQUEST_STOP);
- gSavedPerAccountSettings.setString("AODefaultFall",stranim);
- state = STATE_AGENT_FALLDOWN;
- }
- else if (box->getName() == "hovers")
- {
- gAgent.sendAnimationRequest(GetAnimID(ANIM_AGENT_HOVER), ANIM_REQUEST_STOP);
- gSavedPerAccountSettings.setString("AODefaultHover",stranim);
- state = STATE_AGENT_HOVER;
- }
- else if (box->getName() == "flys")
- {
- gAgent.sendAnimationRequest(GetAnimID(ANIM_AGENT_FLY), ANIM_REQUEST_STOP);
- gSavedPerAccountSettings.setString("AODefaultFly",stranim);
- state = STATE_AGENT_FLY;
- }
- else if (box->getName() == "flyslows")
- {
- gAgent.sendAnimationRequest(GetAnimID(ANIM_AGENT_FLYSLOW), ANIM_REQUEST_STOP);
- gSavedPerAccountSettings.setString("AODefaultFlySlow",stranim);
- state = STATE_AGENT_FLYSLOW;
- }
- else if (box->getName() == "flyups")
- {
- gAgent.sendAnimationRequest(GetAnimID(ANIM_AGENT_HOVER_UP), ANIM_REQUEST_STOP);
- gSavedPerAccountSettings.setString("AODefaultFlyUp",stranim);
- state = STATE_AGENT_HOVER_UP;
- }
- else if (box->getName() == "flydowns")
- {
- gAgent.sendAnimationRequest(GetAnimID(ANIM_AGENT_HOVER_DOWN), ANIM_REQUEST_STOP);
- gSavedPerAccountSettings.setString("AODefaultFlyDown",stranim);
- state = STATE_AGENT_HOVER_DOWN;
- }
- else if (box->getName() == "lands")
- {
- gAgent.sendAnimationRequest(GetAnimID(ANIM_AGENT_LAND), ANIM_REQUEST_STOP);
- gSavedPerAccountSettings.setString("AODefaultLand",stranim);
- state = STATE_AGENT_LAND;
- }
- else if (box->getName() == "standups")
- {
- gAgent.sendAnimationRequest(GetAnimID(ANIM_AGENT_STAND), ANIM_REQUEST_STOP);
- gSavedPerAccountSettings.setString("AODefaultStandUp",stranim);
- state = STATE_AGENT_STAND;
- }
- else if (box->getName() == "prejumps")
- {
- gAgent.sendAnimationRequest(GetAnimID(ANIM_AGENT_PRE_JUMP), ANIM_REQUEST_STOP);
- gSavedPerAccountSettings.setString("AODefaultPreJump",stranim);
- state = STATE_AGENT_PRE_JUMP;
- }
- for (std::vector::iterator iter = mAOOverrides.begin(); iter != mAOOverrides.end(); ++iter)
- {
- if (state == iter->state)
- {
- iter->ao_id = getAssetIDByName(stranim);
+ ao.ao_id = anim;
+ break;
}
}
}
}
}
-void LLFloaterAO::updateLayout(LLFloaterAO* floater)
+void LLFloaterAO::updateLayout(bool advanced)
{
- if (floater)
- {
- BOOL advanced = gSavedSettings.getBOOL( "AOAdvanced");
- if (advanced)
- {
- floater->reshape(610,380); //view->getRect().getWidth(), view->getUIWinHeightLong());
- }
- else
- {
- floater->reshape(200,380); //view->getRect().getWidth(), view->getUIWinHeightShort());
- }
-
- floater->childSetVisible("more_btn", !advanced);
- floater->childSetVisible("less_btn", advanced);
-
- floater->childSetVisible("tabcontainer", advanced);
- floater->childSetVisible("tabdefaultanims", advanced);
-
- floater->childSetVisible("textdefaultwalk", advanced);
- floater->childSetVisible("textdefaultrun", advanced);
- floater->childSetVisible("textdefaultjump", advanced);
- floater->childSetVisible("textdefaultsit", advanced);
- floater->childSetVisible("textdefaultgsit", advanced);
- floater->childSetVisible("textdefaultcrouch", advanced);
- floater->childSetVisible("textdefaultcrouchwalk", advanced);
- floater->childSetVisible("textdefaultfall", advanced);
- floater->childSetVisible("textdefaulthover", advanced);
- floater->childSetVisible("textdefaultfly", advanced);
- floater->childSetVisible("textdefaultflyslow", advanced);
- floater->childSetVisible("textdefaultflyup", advanced);
- floater->childSetVisible("textdefaultflydown", advanced);
- floater->childSetVisible("textdefaultland", advanced);
- floater->childSetVisible("textdefaultstandup", advanced);
- floater->childSetVisible("textdefaultprejump", advanced);
-
-
- floater->childSetVisible("walks", advanced);
- floater->childSetVisible("runs", advanced);
- floater->childSetVisible("jumps", advanced);
- floater->childSetVisible("sits", advanced);
- floater->childSetVisible("gsits", advanced);
- floater->childSetVisible("crouchs", advanced);
- floater->childSetVisible("falls", advanced);
- floater->childSetVisible("hovers", advanced);
- floater->childSetVisible("flys", advanced);
- floater->childSetVisible("flyslows", advanced);
- floater->childSetVisible("flyups", advanced);
- floater->childSetVisible("flydowns", advanced);
- floater->childSetVisible("lands", advanced);
- floater->childSetVisible("standups", advanced);
- floater->childSetVisible("prejumps", advanced);
- }
+ reshape(advanced ? 800 : 200, getRect().getHeight());
+ childSetVisible("tabcontainer", advanced);
}
void LLFloaterAO::init()
{
mAOStands.clear();
- mAOTokens.clear();
mAOOverrides.clear();
- struct_tokens tokenloader;
- tokenloader.token =
- tokenloader.token = "[ Sitting On Ground ]"; tokenloader.state = STATE_AGENT_GROUNDSIT; mAOTokens.push_back(tokenloader); // 0
- tokenloader.token = "[ Sitting ]"; tokenloader.state = STATE_AGENT_SIT; mAOTokens.push_back(tokenloader); // 1
- tokenloader.token = "[ Crouching ]"; tokenloader.state = STATE_AGENT_CROUCH; mAOTokens.push_back(tokenloader); // 3
- tokenloader.token = "[ Crouch Walking ]"; tokenloader.state = STATE_AGENT_CROUCHWALK; mAOTokens.push_back(tokenloader); // 4
- tokenloader.token = "[ Standing Up ]"; tokenloader.state = STATE_AGENT_STANDUP; mAOTokens.push_back(tokenloader); // 6
- tokenloader.token = "[ Falling ]"; tokenloader.state = STATE_AGENT_FALLDOWN; mAOTokens.push_back(tokenloader); // 7
- tokenloader.token = "[ Flying Down ]"; tokenloader.state = STATE_AGENT_HOVER_DOWN; mAOTokens.push_back(tokenloader); // 8
- tokenloader.token = "[ Flying Up ]"; tokenloader.state = STATE_AGENT_HOVER_UP; mAOTokens.push_back(tokenloader); // 9
- tokenloader.token = "[ Flying Slow ]"; tokenloader.state = STATE_AGENT_FLYSLOW; mAOTokens.push_back(tokenloader); // 10
- tokenloader.token = "[ Flying ]"; tokenloader.state = STATE_AGENT_FLY; mAOTokens.push_back(tokenloader); // 11
- tokenloader.token = "[ Hovering ]"; tokenloader.state = STATE_AGENT_HOVER; mAOTokens.push_back(tokenloader); // 12
- tokenloader.token = "[ Jumping ]"; tokenloader.state = STATE_AGENT_JUMP; mAOTokens.push_back(tokenloader); // 13
- tokenloader.token = "[ Pre Jumping ]"; tokenloader.state = STATE_AGENT_PRE_JUMP; mAOTokens.push_back(tokenloader); // 14
- tokenloader.token = "[ Running ]"; tokenloader.state = STATE_AGENT_RUN; mAOTokens.push_back(tokenloader); // 15
- tokenloader.token = "[ Turning Right ]"; tokenloader.state = STATE_AGENT_TURNRIGHT; mAOTokens.push_back(tokenloader); // 16
- tokenloader.token = "[ Turning Left ]"; tokenloader.state = STATE_AGENT_TURNLEFT; mAOTokens.push_back(tokenloader); // 17
- tokenloader.token = "[ Walking ]"; tokenloader.state = STATE_AGENT_WALK; mAOTokens.push_back(tokenloader); // 18
- tokenloader.token = "[ Landing ]"; tokenloader.state = STATE_AGENT_LAND; mAOTokens.push_back(tokenloader); // 19
- tokenloader.token = "[ Standing ]"; tokenloader.state = STATE_AGENT_STAND; mAOTokens.push_back(tokenloader); // 20
- tokenloader.token = "[ Swimming Down ]"; tokenloader.state = 999; mAOTokens.push_back(tokenloader); // 21
- tokenloader.token = "[ Swimming Up ]"; tokenloader.state = 999; mAOTokens.push_back(tokenloader); // 22
- tokenloader.token = "[ Swimming Forward ]"; tokenloader.state = 999; mAOTokens.push_back(tokenloader); // 23
- tokenloader.token = "[ Floating ]"; tokenloader.state = 999; mAOTokens.push_back(tokenloader); // 24
-
struct_overrides overrideloader;
- overrideloader.orig_id = ANIM_AGENT_WALK; overrideloader.ao_id = LLUUID::null; overrideloader.state = STATE_AGENT_WALK; mAOOverrides.push_back(overrideloader);
- overrideloader.orig_id = ANIM_AGENT_RUN; overrideloader.ao_id = LLUUID::null; overrideloader.state = STATE_AGENT_RUN; mAOOverrides.push_back(overrideloader);
- overrideloader.orig_id = ANIM_AGENT_PRE_JUMP; overrideloader.ao_id = LLUUID::null; overrideloader.state = STATE_AGENT_PRE_JUMP; mAOOverrides.push_back(overrideloader);
- overrideloader.orig_id = ANIM_AGENT_JUMP; overrideloader.ao_id = LLUUID::null; overrideloader.state = STATE_AGENT_JUMP; mAOOverrides.push_back(overrideloader);
- overrideloader.orig_id = ANIM_AGENT_TURNLEFT; overrideloader.ao_id = LLUUID::null; overrideloader.state = STATE_AGENT_TURNLEFT; mAOOverrides.push_back(overrideloader);
- overrideloader.orig_id = ANIM_AGENT_TURNRIGHT; overrideloader.ao_id = LLUUID::null; overrideloader.state = STATE_AGENT_TURNRIGHT; mAOOverrides.push_back(overrideloader);
+ overrideloader.orig_id = ANIM_AGENT_WALK; overrideloader.state = STATE_AGENT_WALK; mAOOverrides.push_back(overrideloader);
+ overrideloader.orig_id = ANIM_AGENT_RUN; overrideloader.state = STATE_AGENT_RUN; mAOOverrides.push_back(overrideloader);
+ overrideloader.orig_id = ANIM_AGENT_PRE_JUMP; overrideloader.state = STATE_AGENT_PRE_JUMP; mAOOverrides.push_back(overrideloader);
+ overrideloader.orig_id = ANIM_AGENT_JUMP; overrideloader.state = STATE_AGENT_JUMP; mAOOverrides.push_back(overrideloader);
+ overrideloader.orig_id = ANIM_AGENT_TURNLEFT; overrideloader.state = STATE_AGENT_TURNLEFT; mAOOverrides.push_back(overrideloader);
+ overrideloader.orig_id = ANIM_AGENT_TURNRIGHT; overrideloader.state = STATE_AGENT_TURNRIGHT; mAOOverrides.push_back(overrideloader);
- overrideloader.orig_id = ANIM_AGENT_SIT; overrideloader.ao_id = LLUUID::null; overrideloader.state = STATE_AGENT_SIT; mAOOverrides.push_back(overrideloader);
- overrideloader.orig_id = ANIM_AGENT_SIT_FEMALE; overrideloader.ao_id = LLUUID::null; overrideloader.state = STATE_AGENT_SIT; mAOOverrides.push_back(overrideloader);
- overrideloader.orig_id = ANIM_AGENT_SIT_GENERIC; overrideloader.ao_id = LLUUID::null; overrideloader.state = STATE_AGENT_SIT; mAOOverrides.push_back(overrideloader);
- overrideloader.orig_id = ANIM_AGENT_SIT_GROUND; overrideloader.ao_id = LLUUID::null; overrideloader.state = STATE_AGENT_GROUNDSIT; mAOOverrides.push_back(overrideloader);
- overrideloader.orig_id = ANIM_AGENT_SIT_GROUND_CONSTRAINED; overrideloader.ao_id = LLUUID::null; overrideloader.state = STATE_AGENT_GROUNDSIT; mAOOverrides.push_back(overrideloader);
+ overrideloader.orig_id = ANIM_AGENT_SIT; overrideloader.state = STATE_AGENT_SIT; mAOOverrides.push_back(overrideloader);
+ overrideloader.orig_id = ANIM_AGENT_SIT_FEMALE; overrideloader.state = STATE_AGENT_SIT; mAOOverrides.push_back(overrideloader);
+ overrideloader.orig_id = ANIM_AGENT_SIT_GENERIC; overrideloader.state = STATE_AGENT_SIT; mAOOverrides.push_back(overrideloader);
+ overrideloader.orig_id = ANIM_AGENT_SIT_GROUND; overrideloader.state = STATE_AGENT_GROUNDSIT; mAOOverrides.push_back(overrideloader);
+ overrideloader.orig_id = ANIM_AGENT_SIT_GROUND_CONSTRAINED; overrideloader.state = STATE_AGENT_GROUNDSIT; mAOOverrides.push_back(overrideloader);
- overrideloader.orig_id = ANIM_AGENT_HOVER; overrideloader.ao_id = LLUUID::null; overrideloader.state = STATE_AGENT_HOVER; mAOOverrides.push_back(overrideloader);
- overrideloader.orig_id = ANIM_AGENT_HOVER_DOWN; overrideloader.ao_id = LLUUID::null; overrideloader.state = STATE_AGENT_HOVER_DOWN; mAOOverrides.push_back(overrideloader);
- overrideloader.orig_id = ANIM_AGENT_HOVER_UP; overrideloader.ao_id = LLUUID::null; overrideloader.state = STATE_AGENT_HOVER_UP; mAOOverrides.push_back(overrideloader);
+ overrideloader.orig_id = ANIM_AGENT_HOVER; overrideloader.state = STATE_AGENT_HOVER; mAOOverrides.push_back(overrideloader);
+ overrideloader.orig_id = ANIM_AGENT_HOVER_DOWN; overrideloader.state = STATE_AGENT_HOVER_DOWN; mAOOverrides.push_back(overrideloader);
+ overrideloader.orig_id = ANIM_AGENT_HOVER_UP; overrideloader.state = STATE_AGENT_HOVER_UP; mAOOverrides.push_back(overrideloader);
- overrideloader.orig_id = ANIM_AGENT_CROUCH; overrideloader.ao_id = LLUUID::null; overrideloader.state = STATE_AGENT_CROUCH; mAOOverrides.push_back(overrideloader);
- overrideloader.orig_id = ANIM_AGENT_CROUCHWALK; overrideloader.ao_id = LLUUID::null; overrideloader.state = STATE_AGENT_CROUCHWALK; mAOOverrides.push_back(overrideloader);
+ overrideloader.orig_id = ANIM_AGENT_CROUCH; overrideloader.state = STATE_AGENT_CROUCH; mAOOverrides.push_back(overrideloader);
+ overrideloader.orig_id = ANIM_AGENT_CROUCHWALK; overrideloader.state = STATE_AGENT_CROUCHWALK; mAOOverrides.push_back(overrideloader);
- overrideloader.orig_id = ANIM_AGENT_FALLDOWN; overrideloader.ao_id = LLUUID::null; overrideloader.state = STATE_AGENT_FALLDOWN; mAOOverrides.push_back(overrideloader);
- overrideloader.orig_id = ANIM_AGENT_STANDUP; overrideloader.ao_id = LLUUID::null; overrideloader.state = STATE_AGENT_STANDUP; mAOOverrides.push_back(overrideloader);
- overrideloader.orig_id = ANIM_AGENT_LAND; overrideloader.ao_id = LLUUID::null; overrideloader.state = STATE_AGENT_LAND; mAOOverrides.push_back(overrideloader);
+ overrideloader.orig_id = ANIM_AGENT_FALLDOWN; overrideloader.state = STATE_AGENT_FALLDOWN; mAOOverrides.push_back(overrideloader);
+ overrideloader.orig_id = ANIM_AGENT_STANDUP; overrideloader.state = STATE_AGENT_STANDUP; mAOOverrides.push_back(overrideloader);
+ overrideloader.orig_id = ANIM_AGENT_LAND; overrideloader.state = STATE_AGENT_LAND; mAOOverrides.push_back(overrideloader);
+ overrideloader.orig_id = ANIM_AGENT_TYPE; overrideloader.state = STATE_AGENT_TYPING; mAOOverrides.push_back(overrideloader);
- overrideloader.orig_id = ANIM_AGENT_FLY; overrideloader.ao_id = LLUUID::null; overrideloader.state = STATE_AGENT_FLY; mAOOverrides.push_back(overrideloader);
- overrideloader.orig_id = ANIM_AGENT_FLYSLOW; overrideloader.ao_id = LLUUID::null; overrideloader.state = STATE_AGENT_FLYSLOW; mAOOverrides.push_back(overrideloader);
+ overrideloader.orig_id = ANIM_AGENT_FLY; overrideloader.state = STATE_AGENT_FLY; mAOOverrides.push_back(overrideloader);
+ overrideloader.orig_id = ANIM_AGENT_FLYSLOW; overrideloader.state = STATE_AGENT_FLYSLOW; mAOOverrides.push_back(overrideloader);
- BOOL success = TRUE;
+ overrideloader.orig_id = ANIM_AGENT_HOVER; overrideloader.state = STATE_AGENT_FLOAT; mAOOverrides.push_back(overrideloader);
+ overrideloader.orig_id = ANIM_AGENT_HOVER_DOWN; overrideloader.state = STATE_AGENT_SWIM_DOWN; mAOOverrides.push_back(overrideloader);
+ overrideloader.orig_id = ANIM_AGENT_HOVER_UP; overrideloader.state = STATE_AGENT_SWIM_UP; mAOOverrides.push_back(overrideloader);
+
+ overrideloader.orig_id = ANIM_AGENT_FLY; overrideloader.state = STATE_AGENT_SWIM; mAOOverrides.push_back(overrideloader);
+
+ bool success = true;
if(LLStartUp::getStartupState() >= STATE_INVENTORY_SEND)
{
@@ -572,7 +377,7 @@ void LLFloaterAO::init()
LLUUID configncitem = (LLUUID)gSavedPerAccountSettings.getString("AOConfigNotecardID");
if (configncitem.notNull())
{
- success = FALSE;
+ success = false;
const LLInventoryItem* item = gInventory.getItem(configncitem);
if(item)
{
@@ -593,8 +398,8 @@ void LLFloaterAO::init()
item->getType(),
&onNotecardLoadComplete,
(void*)new_uuid,
- TRUE);
- success = TRUE;
+ true);
+ success = true;
}
}
}
@@ -607,41 +412,20 @@ void LLFloaterAO::init()
cmdline_printchat("Could not read the specified Config Notecard");
}
-// mAnimationState = 0;
+// mAnimationState = STATE_AGENT_IDLE;
// mCurrentStandId = LLUUID::null;
// setAnimationState(STATE_AGENT_IDLE);
-
-}
-
-void LLFloaterAO::onClickMore(void* data)
-{
- gSavedSettings.setBOOL( "AOAdvanced", TRUE );
- updateLayout(sInstance);
-}
-void LLFloaterAO::onClickLess(void* data)
-{
- gSavedSettings.setBOOL( "AOAdvanced", FALSE );
- updateLayout(sInstance);
-}
-
-void LLFloaterAO::onClickToggleAO()
-{
- run();
-}
-
-void LLFloaterAO::onClickToggleSits()
-{
- run();
}
void LLFloaterAO::run()
{
setAnimationState(STATE_AGENT_IDLE); // reset state
- int state = getAnimationState(); // check if sitting or hovering
- if ((state == STATE_AGENT_IDLE) || (state == STATE_AGENT_STAND))
+ AOState state = getAnimationState(); // check if sitting or hovering
+ bool enabled = gSavedSettings.getBOOL("AOEnabled");
+ if (state == STATE_AGENT_IDLE || state == STATE_AGENT_STAND)
{
- if (gSavedSettings.getBOOL("AOEnabled"))
+ if (enabled)
{
if (mAOStandTimer)
{
@@ -655,18 +439,63 @@ void LLFloaterAO::run()
}
else
{
- stopMotion(getCurrentStandId(), FALSE, TRUE); //stop stand first then set state
+ stopMotion(getCurrentStandId(), true); //stop stand first then set state
setAnimationState(STATE_AGENT_IDLE);
}
}
else
{
- if (state == STATE_AGENT_SIT) gAgent.sendAnimationRequest(GetAnimIDFromState(state), (gSavedSettings.getBOOL("AOEnabled") && gSavedSettings.getBOOL("AOSitsEnabled")) ? ANIM_REQUEST_START : ANIM_REQUEST_STOP);
- else gAgent.sendAnimationRequest(GetAnimIDFromState(state), gSavedSettings.getBOOL("AOEnabled") ? ANIM_REQUEST_START : ANIM_REQUEST_STOP);
+ bool sit = false;
+ switch (state)
+ {
+ case STATE_AGENT_SIT:
+ case STATE_AGENT_GROUNDSIT:
+ sit = true;
+ stopMotion(getCurrentStandId(), true); // Stop the current stand
+ break;
+ default: break;
+ }
+ gAgent.sendAnimationRequest(GetAnimIDFromState(state), (enabled && (!sit || gSavedSettings.getBOOL("AOSitsEnabled"))) ? ANIM_REQUEST_START : ANIM_REQUEST_STOP);
}
}
-int LLFloaterAO::getAnimationState()
+void LLFloaterAO::typing(bool start)
+{
+ uuid_vec_t anims;
+ // If we're stopping, stop regardless, just in case the setting was toggled during (e.g.: keyboard shortcut)
+ if (!start || gSavedSettings.getBOOL("PlayTypingAnim")) // Linden typing
+ anims.push_back(ANIM_AGENT_TYPE);
+ if (gSavedSettings.getBOOL("AOEnabled")) // Typing override
+ anims.push_back(GetAnimIDFromState(STATE_AGENT_TYPING));
+ if (anims.empty()) return;
+ gAgent.sendAnimationRequests(anims, start ? ANIM_REQUEST_START : ANIM_REQUEST_STOP);
+}
+
+AOState LLFloaterAO::flyToSwimState(const AOState& state)
+{
+ switch (state)
+ {
+ case STATE_AGENT_HOVER: return STATE_AGENT_FLOAT;
+ case STATE_AGENT_FLY: return STATE_AGENT_SWIM;
+ case STATE_AGENT_HOVER_UP: return STATE_AGENT_SWIM_UP;
+ case STATE_AGENT_HOVER_DOWN: return STATE_AGENT_SWIM_DOWN;
+ default: return state;
+ }
+}
+
+AOState LLFloaterAO::swimToFlyState(const AOState& state)
+{
+ switch (state)
+ {
+ case STATE_AGENT_FLOAT: return STATE_AGENT_HOVER;
+ case STATE_AGENT_SWIM: return STATE_AGENT_FLY;
+ case STATE_AGENT_SWIM_UP: return STATE_AGENT_HOVER_UP;
+ case STATE_AGENT_SWIM_DOWN: return STATE_AGENT_HOVER_DOWN;
+ default: return state;
+ }
+}
+
+AOState LLFloaterAO::getAnimationState()
{
if (gAgentAvatarp)
{
@@ -676,9 +505,9 @@ int LLFloaterAO::getAnimationState()
return mAnimationState;
}
-void LLFloaterAO::setAnimationState(const int state)
+void LLFloaterAO::setAnimationState(const AOState& state)
{
- mAnimationState = state;
+ mAnimationState = sSwimming ? flyToSwimState(state) : state;
}
LLUUID LLFloaterAO::getCurrentStandId()
@@ -691,81 +520,113 @@ void LLFloaterAO::setCurrentStandId(const LLUUID& id)
mCurrentStandId = id;
}
+bool LLFloaterAO::swimCheck(const AOState& state)
+{
+ switch (state)
+ {
+ case STATE_AGENT_HOVER:
+ case STATE_AGENT_FLY:
+ case STATE_AGENT_HOVER_UP:
+ case STATE_AGENT_HOVER_DOWN:
+ return !sSwimming;
+ case STATE_AGENT_FLOAT:
+ case STATE_AGENT_SWIM:
+ case STATE_AGENT_SWIM_UP:
+ case STATE_AGENT_SWIM_DOWN:
+ return sSwimming;
+ default: return true;
+ }
+}
+
LLUUID LLFloaterAO::GetAnimID(const LLUUID& id)
{
- for (std::vector::iterator iter = mAOOverrides.begin(); iter != mAOOverrides.end(); ++iter)
+ for (const auto& ao : mAOOverrides)
{
- if (iter->orig_id == id) return iter->ao_id;
+ if (swimCheck(ao.state) && ao.orig_id == id)
+ {
+ return ao.ao_id;
+ }
}
return LLUUID::null;
}
-int LLFloaterAO::GetStateFromAnimID(const LLUUID& id)
+AOState LLFloaterAO::GetStateFromAnimID(const LLUUID& id)
{
- for (std::vector::iterator iter = mAOOverrides.begin(); iter != mAOOverrides.end(); ++iter)
+ for (const auto& ao : mAOOverrides)
{
- if (iter->orig_id == id) return iter->state;
+ if (swimCheck(ao.state) && ao.orig_id == id) return ao.state;
}
return STATE_AGENT_IDLE;
}
-LLUUID LLFloaterAO::GetAnimIDFromState(const int state)
+LLUUID LLFloaterAO::GetAnimIDFromState(const AOState& state)
{
- for (std::vector::iterator iter = mAOOverrides.begin(); iter != mAOOverrides.end(); ++iter)
+ for (const auto& ao : mAOOverrides)
{
- if (iter->state == state) return iter->ao_id;
+ if (ao.state == state) return ao.ao_id;
}
return LLUUID::null;
}
-int LLFloaterAO::GetStateFromToken(std::string strtoken)
+AOState LLFloaterAO::GetStateFromToken(std::string strtoken)
{
- for (std::vector::iterator iter = mAOTokens.begin(); iter != mAOTokens.end(); ++iter)
- {
- if (iter->token == strtoken) return iter->state;
- }
+ if (strtoken == "[ Sitting On Ground ]") return STATE_AGENT_GROUNDSIT;
+ if (strtoken == "[ Sitting ]") return STATE_AGENT_SIT;
+ if (strtoken == "[ Crouching ]") return STATE_AGENT_CROUCH;
+ if (strtoken == "[ Crouch Walking ]") return STATE_AGENT_CROUCHWALK;
+ if (strtoken == "[ Standing Up ]") return STATE_AGENT_STANDUP;
+ if (strtoken == "[ Falling ]") return STATE_AGENT_FALLDOWN;
+ if (strtoken == "[ Flying Down ]") return STATE_AGENT_HOVER_DOWN;
+ if (strtoken == "[ Flying Up ]") return STATE_AGENT_HOVER_UP;
+ if (strtoken == "[ Flying Slow ]") return STATE_AGENT_FLYSLOW;
+ if (strtoken == "[ Flying ]") return STATE_AGENT_FLY;
+ if (strtoken == "[ Hovering ]") return STATE_AGENT_HOVER;
+ if (strtoken == "[ Jumping ]") return STATE_AGENT_JUMP;
+ if (strtoken == "[ Pre Jumping ]") return STATE_AGENT_PRE_JUMP;
+ if (strtoken == "[ Running ]") return STATE_AGENT_RUN;
+ if (strtoken == "[ Turning Right ]") return STATE_AGENT_TURNRIGHT;
+ if (strtoken == "[ Turning Left ]") return STATE_AGENT_TURNLEFT;
+ if (strtoken == "[ Walking ]") return STATE_AGENT_WALK;
+ if (strtoken == "[ Landing ]") return STATE_AGENT_LAND;
+ if (strtoken == "[ Standing ]") return STATE_AGENT_STAND;
+ if (strtoken == "[ Swimming Down ]") return STATE_AGENT_SWIM_DOWN;
+ if (strtoken == "[ Swimming Up ]") return STATE_AGENT_SWIM_UP;
+ if (strtoken == "[ Swimming Forward ]") return STATE_AGENT_SWIM;
+ if (strtoken == "[ Floating ]") return STATE_AGENT_FLOAT;
+ if (strtoken == "[ Typing ]") return STATE_AGENT_TYPING;
return STATE_AGENT_IDLE;
}
-void LLFloaterAO::onClickPrevStand(void* user_data)
+void LLFloaterAO::onClickCycleStand(bool next)
{
- if (!(mAOStands.size() > 0)) return;
- stand_iterator=stand_iterator-1;
+ if (mAOStands.empty()) return;
+ stand_iterator += (next ? 1 : -1);
if (stand_iterator < 0) stand_iterator = int( mAOStands.size()-stand_iterator);
if (stand_iterator > int( mAOStands.size()-1)) stand_iterator = 0;
cmdline_printchat(llformat("Changing stand to %s.",mAOStands[stand_iterator].anim_name.c_str()));
ChangeStand();
}
-void LLFloaterAO::onClickNextStand(void* user_data)
-{
- if (!(mAOStands.size() > 0)) return;
- stand_iterator=stand_iterator+1;
- if (stand_iterator < 0) stand_iterator = int( mAOStands.size()-stand_iterator);
- if (stand_iterator > int( mAOStands.size()-1)) stand_iterator = 0;
- cmdline_printchat(llformat("Changing stand to %s.",mAOStands[stand_iterator].anim_name.c_str()));
- ChangeStand();
-}
-
-BOOL LLFloaterAO::ChangeStand()
+void LLFloaterAO::ChangeStand()
{
if (gSavedSettings.getBOOL("AOEnabled"))
{
if (gAgentAvatarp)
{
- if (gSavedSettings.getBOOL("AONoStandsInMouselook") && gAgentCamera.cameraMouselook()) return FALSE;
+ if (gSavedSettings.getBOOL("AONoStandsInMouselook") && gAgentCamera.cameraMouselook()) return;
if (gAgentAvatarp->isSitting())
{
-// stopMotion(getCurrentStandId(), FALSE, TRUE); //stop stand first then set state
+// stopMotion(getCurrentStandId(), true); //stop stand first then set state
// if (getAnimationState() != STATE_AGENT_GROUNDSIT) setAnimationState(STATE_AGENT_SIT);
// setCurrentStandId(LLUUID::null);
- return FALSE;
+ return;
}
}
- if ((getAnimationState() == STATE_AGENT_IDLE) || (getAnimationState() == STATE_AGENT_STAND))// stands have lowest priority
+ AOState state = getAnimationState();
+ if (state == STATE_AGENT_IDLE || state == STATE_AGENT_STAND)// stands have lowest priority
{
- if (!(mAOStands.size() > 0)) return TRUE;
+ if (mAOStands.empty()) return;
if (gSavedSettings.getBOOL("AOStandRandomize"))
{
stand_iterator = ll_rand(mAOStands.size()-1);
@@ -779,113 +640,107 @@ BOOL LLFloaterAO::ChangeStand()
if (mAOStands[stand_iterator].ao_id.notNull())
{
- stopMotion(getCurrentStandId(), FALSE, TRUE); //stop stand first then set state
- startMotion(mAOStands[stand_iterator].ao_id, 0, TRUE);
+ stopMotion(getCurrentStandId(), true); //stop stand first then set state
+ startMotion(mAOStands[stand_iterator].ao_id, true);
setAnimationState(STATE_AGENT_STAND);
setCurrentStandId(mAOStands[stand_iterator].ao_id);
- if ((sInstance)&&(mcomboBox_stands)) mcomboBox_stands->selectNthItem(stand_iterator);
+ if (mcomboBox_stands) mcomboBox_stands->selectNthItem(stand_iterator);
// LL_INFOS() << "changing stand to " << mAOStands[stand_iterator].anim_name << LL_ENDL;
- return FALSE;
}
}
}
- else
- {
- stopMotion(getCurrentStandId(), FALSE, TRUE);
- return TRUE; //stop if ao is off
- }
- return TRUE;
+ else stopMotion(getCurrentStandId(), true);
}
-
-BOOL LLFloaterAO::startMotion(const LLUUID& id, F32 time_offset, BOOL stand)
+void LLFloaterAO::toggleSwim(bool underwater)
{
+ static const LLCachedControl enabled(gSavedSettings, "AOEnabled", false);
+
+ sSwimming = underwater && enable_swim();
+
+ // Don't send requests if we have the AO disabled.
+ if (enabled)
+ {
+ AOState state = getAnimationState();
+ if (state != STATE_AGENT_IDLE && state != STATE_AGENT_STAND) // Don't bother if we're just standing or idle (Who pushed us?!)
+ {
+ // Stop all of the previous states
+ constexpr std::array swim_states = { STATE_AGENT_FLOAT, STATE_AGENT_SWIM, STATE_AGENT_SWIM_UP, STATE_AGENT_SWIM_DOWN };
+ constexpr std::array fly_states = { STATE_AGENT_HOVER, STATE_AGENT_FLY, STATE_AGENT_HOVER_UP, STATE_AGENT_HOVER_DOWN };
+ uuid_vec_t vec;
+ for (const auto& state : sSwimming ? fly_states : swim_states)
+ vec.push_back(GetAnimIDFromState(state));
+ gAgent.sendAnimationRequests(vec, ANIM_REQUEST_STOP);
+ // Process new animations
+ gAgentAvatarp->processAnimationStateChanges();
+ }
+ }
+}
+
+void LLFloaterAO::doMotion(const LLUUID& id, bool start, bool stand)
+{
+ if (id.isNull()) return;
+ LLUUID anim = id;
if (stand)
{
- if (id.notNull())
+ if (start)
{
- BOOL sitting = FALSE;
- if (gAgentAvatarp)
- {
- sitting = gAgentAvatarp->isSitting();
- }
- if (sitting) return FALSE;
- gAgent.sendAnimationRequest(id, ANIM_REQUEST_START);
- return TRUE;
+ if (gAgentAvatarp && gAgentAvatarp->isSitting())
+ return;
}
+ else setAnimationState(STATE_AGENT_IDLE);
}
else
{
- if (GetAnimID(id).notNull() && gSavedSettings.getBOOL("AOEnabled"))
+ anim = GetAnimID(id);
+ if (anim.isNull() || !gSavedSettings.getBOOL("AOEnabled")) return;
+ AOState state = GetStateFromAnimID(id);
+ if (start)
{
- stopMotion(getCurrentStandId(), FALSE, TRUE); //stop stand first then set state
- setAnimationState(GetStateFromAnimID(id));
-
-// LL_INFOS() << " state " << getAnimationState() << " start anim " << id << " overriding with " << GetAnimID(id) << LL_ENDL;
- if ((GetStateFromAnimID(id) == STATE_AGENT_SIT) && !(gSavedSettings.getBOOL("AOSitsEnabled"))) return TRUE;
- gAgent.sendAnimationRequest(GetAnimID(id), ANIM_REQUEST_START);
- return TRUE;
+ stopMotion(getCurrentStandId(), true); //stop stand first then set state
+ setAnimationState(state);
+// LL_INFOS() << " state " << getAnimationState() << " start anim " << id << " overriding with " << anim << LL_ENDL;
+ if (state == STATE_AGENT_SIT && !gSavedSettings.getBOOL("AOSitsEnabled")) return;
+ }
+ else
+ {
+// LL_INFOS() << " state " << getAnimationState() << "/" << state << "(now 0) stop anim " << id << " overriding with " << anim << LL_ENDL;
+ if (getAnimationState() == state) setAnimationState(STATE_AGENT_IDLE);
+ ChangeStand(); // startMotion(getCurrentStandId(), true);
}
}
- return FALSE;
+ gAgent.sendAnimationRequest(anim, start ? ANIM_REQUEST_START : ANIM_REQUEST_STOP);
}
-BOOL LLFloaterAO::stopMotion(const LLUUID& id, BOOL stop_immediate, BOOL stand)
-{
- if (stand)
- {
- setAnimationState(STATE_AGENT_IDLE);
- gAgent.sendAnimationRequest(id, ANIM_REQUEST_STOP);
- return TRUE;
- }
- else
- {
- if (GetAnimID(id).notNull() && gSavedSettings.getBOOL("AOEnabled"))
- {
-// LL_INFOS() << " state " << getAnimationState() << "/" << GetStateFromAnimID(id) << "(now 0) stop anim " << id << " overriding with " << GetAnimID(id) << LL_ENDL;
- if (getAnimationState() == GetStateFromAnimID(id))
- {
- setAnimationState(STATE_AGENT_IDLE);
- }
- ChangeStand(); // startMotion(getCurrentStandId(), 0, TRUE);
- gAgent.sendAnimationRequest(GetAnimID(id), ANIM_REQUEST_STOP);
- return TRUE;
- }
- }
- return FALSE;
-}
-
-void LLFloaterAO::onClickReloadCard(void* user_data)
+void LLFloaterAO::onClickReloadCard()
{
- if(LLInventoryModelBackgroundFetch::instance().isEverythingFetched())
+ if (LLInventoryModelBackgroundFetch::instance().isEverythingFetched())
{
- LLFloaterAO::init();
+ init();
}
}
-void LLFloaterAO::onClickOpenCard(void* user_data)
+void LLFloaterAO::onClickOpenCard()
{
- if(LLInventoryModelBackgroundFetch::instance().isEverythingFetched())
+ if (LLInventoryModelBackgroundFetch::instance().isEverythingFetched())
{
LLUUID configncitem = (LLUUID)gSavedPerAccountSettings.getString("AOConfigNotecardID");
if (configncitem.notNull())
{
- const LLInventoryItem* item = gInventory.getItem(configncitem);
- if(item)
+ if (LLViewerInventoryItem* item = gInventory.getItem(configncitem))
{
if (gAgent.allowOperation(PERM_COPY, item->getPermissions(),GP_OBJECT_MANIPULATE) || gAgent.isGodlike())
{
if(!item->getAssetUUID().isNull())
- open_notecard((LLViewerInventoryItem*)item, std::string("Note: ") + item->getName(), LLUUID::null, FALSE);
- // open_notecard((LLViewerInventoryItem*)item, std::string("Note: ") + item->getName(), LLUUID::null, FALSE, LLUUID::null, FALSE);
+ open_notecard(item, "Note: " + item->getName(), LLUUID::null, false);
}
}
}
}
}
-void LLFloaterAO::onClickNewCard(void* user_data)
+void LLFloaterAO::onClickNewCard()
{
// load the template file from app_settings/ao_template.ini then
// create a new properly-formatted notecard in the user's inventory
@@ -893,7 +748,7 @@ void LLFloaterAO::onClickNewCard(void* user_data)
if (!ao_template.empty())
{
LLPointer cb = new AONotecardCallback(ao_template);
- create_inventory_item(gAgent.getID(), gAgent.getSessionID(),
+ create_inventory_item(gAgentID, gAgentSessionID,
LLUUID::null, LLTransactionID::tnull, "New AO Notecard",
"Drop this notecard in your AO window to use", LLAssetType::AT_NOTECARD,
LLInventoryType::IT_NOTECARD, NOT_WEARABLE, PERM_ALL, cb);
@@ -906,10 +761,66 @@ void LLFloaterAO::onClickNewCard(void* user_data)
struct AOAssetInfo
{
- std::string path;
- std::string name;
+ std::string path, name;
};
+AOState LLFloaterAO::getStateFromCombo(const LLComboBox* combo)
+{
+ if (combo == mcomboBox_stands) return STATE_AGENT_STAND;
+ if (combo == mcomboBox_walks) return STATE_AGENT_WALK;
+ if (combo == mcomboBox_runs) return STATE_AGENT_RUN;
+ if (combo == mcomboBox_jumps) return STATE_AGENT_JUMP;
+ if (combo == mcomboBox_sits) return STATE_AGENT_SIT;
+ if (combo == mcomboBox_gsits) return STATE_AGENT_GROUNDSIT;
+ if (combo == mcomboBox_crouchs) return STATE_AGENT_CROUCH;
+ if (combo == mcomboBox_cwalks) return STATE_AGENT_CROUCHWALK;
+ if (combo == mcomboBox_falls) return STATE_AGENT_FALLDOWN;
+ if (combo == mcomboBox_hovers) return STATE_AGENT_HOVER;
+ if (combo == mcomboBox_flys) return STATE_AGENT_FLY;
+ if (combo == mcomboBox_flyslows) return STATE_AGENT_FLYSLOW;
+ if (combo == mcomboBox_flyups) return STATE_AGENT_HOVER_UP;
+ if (combo == mcomboBox_flydowns) return STATE_AGENT_HOVER_DOWN;
+ if (combo == mcomboBox_lands) return STATE_AGENT_LAND;
+ if (combo == mcomboBox_typings) return STATE_AGENT_TYPING;
+ if (combo == mcomboBox_floats) return STATE_AGENT_FLOAT;
+ if (combo == mcomboBox_swims) return STATE_AGENT_SWIM;
+ if (combo == mcomboBox_swimups) return STATE_AGENT_SWIM_UP;
+ if (combo == mcomboBox_swimdowns) return STATE_AGENT_SWIM_DOWN;
+ if (combo == mcomboBox_standups) return STATE_AGENT_STANDUP;
+ if (combo == mcomboBox_prejumps) return STATE_AGENT_PRE_JUMP;
+ return STATE_AGENT_IDLE;
+}
+
+LLComboBox* LLFloaterAO::getComboFromState(const AOState& state)
+{
+ switch (state)
+ {
+ case STATE_AGENT_STAND: return mcomboBox_stands;
+ case STATE_AGENT_WALK: return mcomboBox_walks;
+ case STATE_AGENT_RUN: return mcomboBox_runs;
+ case STATE_AGENT_JUMP: return mcomboBox_jumps;
+ case STATE_AGENT_SIT: return mcomboBox_sits;
+ case STATE_AGENT_GROUNDSIT: return mcomboBox_gsits;
+ case STATE_AGENT_CROUCH: return mcomboBox_crouchs;
+ case STATE_AGENT_CROUCHWALK: return mcomboBox_cwalks;
+ case STATE_AGENT_FALLDOWN: return mcomboBox_falls;
+ case STATE_AGENT_HOVER: return mcomboBox_hovers;
+ case STATE_AGENT_FLY: return mcomboBox_flys;
+ case STATE_AGENT_FLYSLOW: return mcomboBox_flyslows;
+ case STATE_AGENT_HOVER_UP: return mcomboBox_flyups;
+ case STATE_AGENT_HOVER_DOWN: return mcomboBox_flydowns;
+ case STATE_AGENT_LAND: return mcomboBox_lands;
+ case STATE_AGENT_TYPING: return mcomboBox_typings;
+ case STATE_AGENT_FLOAT: return mcomboBox_floats;
+ case STATE_AGENT_SWIM: return mcomboBox_swims;
+ case STATE_AGENT_SWIM_UP: return mcomboBox_swimups;
+ case STATE_AGENT_SWIM_DOWN: return mcomboBox_swimdowns;
+ case STATE_AGENT_STANDUP: return mcomboBox_standups;
+ case STATE_AGENT_PRE_JUMP: return mcomboBox_prejumps;
+ default: return nullptr;
+ }
+}
+
void LLFloaterAO::onNotecardLoadComplete(LLVFS *vfs,const LLUUID& asset_uuid,LLAssetType::EType type,void* user_data, S32 status, LLExtStat ext_status)
{
if(status == LL_ERR_NOERR)
@@ -946,187 +857,66 @@ void LLFloaterAO::onNotecardLoadComplete(LLVFS *vfs,const LLUUID& asset_uuid,LLA
if (mcomboBox_flyups) mcomboBox_flyups->clear();
if (mcomboBox_flydowns) mcomboBox_flydowns->clear();
if (mcomboBox_lands) mcomboBox_lands->clear();
+ if (mcomboBox_typings) mcomboBox_typings->clear();
+ if (mcomboBox_floats) mcomboBox_floats->clear();
+ if (mcomboBox_swims) mcomboBox_swims->clear();
+ if (mcomboBox_swimups) mcomboBox_swimups->clear();
+ if (mcomboBox_swimdowns) mcomboBox_swimdowns->clear();
if (mcomboBox_standups) mcomboBox_standups->clear();
if (mcomboBox_prejumps) mcomboBox_prejumps->clear();
-
- struct_stands loader;
-
typedef boost::tokenizer > tokenizer;
boost::char_separator sep("\n");
tokenizer tokline(card, sep);
- for (tokenizer::iterator line = tokline.begin(); line != tokline.end(); ++line)
+ for (const auto& strline : tokline)
{
-// LL_INFOS() << *line << LL_ENDL;
- std::string strline(*line);
// LL_INFOS() << "uncommented line: " << strline << LL_ENDL;
boost::regex type("^(\\s*)(\\[ )(.*)( \\])");
boost::smatch what;
if (boost::regex_search(strline, what, type))
{
-// LL_INFOS() << "type: " << what[0] << LL_ENDL;
+ std::string strtoken(what[0]);
+// LL_INFOS() << "type: " << strtoken << LL_ENDL;
// LL_INFOS() << "anims in type: " << boost::regex_replace(strline, type, "") << LL_ENDL;
boost::char_separator sep("|,");
std::string stranimnames(boost::regex_replace(strline, type, ""));
tokenizer tokanimnames(stranimnames, sep);
- for (tokenizer::iterator anim = tokanimnames.begin(); anim != tokanimnames.end(); ++anim)
+ for (const auto& stranim : tokanimnames)
{
- std::string strtoken(what[0]);
- std::string stranim(*anim);
LLUUID animid(getAssetIDByName(stranim));
// LL_INFOS() << invfolderid.asString().c_str() << LL_ENDL;
// LL_INFOS() << "anim: " << stranim.c_str() << " assetid: " << animid << LL_ENDL;
- if (!(animid.notNull()))
+ if (animid.isNull())
{
cmdline_printchat(llformat("Warning: animation '%s' could not be found (Section: %s).",stranim.c_str(),strtoken.c_str()));
}
else
{
- switch(GetStateFromToken(strtoken.c_str()))
+ const AOState state = GetStateFromToken(strtoken);
+ switch (state)
{
case STATE_AGENT_STAND:
- loader.ao_id = animid; loader.anim_name = stranim.c_str(); mAOStands.push_back(loader);
- if(mcomboBox_stands != NULL) mcomboBox_stands->add(stranim.c_str(), ADD_BOTTOM, TRUE);
- break;
- case STATE_AGENT_WALK:
- {
- if (sInstance && (mcomboBox_walks != NULL))
- {
- //LL_INFOS() << "1 anim: " << stranim.c_str() << " assetid: " << animid << LL_ENDL;
- if (!(mcomboBox_walks->selectByValue(stranim.c_str()))) mcomboBox_walks->add(stranim.c_str(), ADD_BOTTOM, TRUE); //check if exist
- }
- }
- break;
- case STATE_AGENT_RUN:
- {
- if (sInstance && (mcomboBox_runs != NULL))
- {
- if (!(mcomboBox_runs->selectByValue(stranim.c_str()))) mcomboBox_runs->add(stranim.c_str(), ADD_BOTTOM, TRUE); //check if exist
- }
- }
- break;
- case STATE_AGENT_JUMP:
- {
- if (sInstance && (mcomboBox_jumps != NULL))
- {
- if (!(mcomboBox_jumps->selectByValue(stranim.c_str()))) mcomboBox_jumps->add(stranim.c_str(), ADD_BOTTOM, TRUE); //check if exist
- }
- }
- break;
- case STATE_AGENT_SIT:
- {
- if (sInstance && (mcomboBox_sits != NULL))
- {
- if (!(mcomboBox_sits->selectByValue(stranim.c_str()))) mcomboBox_sits->add(stranim.c_str(), ADD_BOTTOM, TRUE); //check if exist
- }
- }
- break;
- case STATE_AGENT_GROUNDSIT:
- {
- if (sInstance && (mcomboBox_gsits != NULL))
- {
- if (!(mcomboBox_gsits->selectByValue(stranim.c_str()))) mcomboBox_gsits->add(stranim.c_str(), ADD_BOTTOM, TRUE); //check if exist
- }
- }
- break;
- case STATE_AGENT_CROUCH:
- {
- if (sInstance && (mcomboBox_crouchs != NULL))
- {
- if (!(mcomboBox_crouchs->selectByValue(stranim.c_str()))) mcomboBox_crouchs->add(stranim.c_str(), ADD_BOTTOM, TRUE); //check if exist
- }
- }
- break;
- case STATE_AGENT_CROUCHWALK:
- {
- if (sInstance && (mcomboBox_cwalks != NULL))
- {
- if (!(mcomboBox_cwalks->selectByValue(stranim.c_str()))) mcomboBox_cwalks->add(stranim.c_str(), ADD_BOTTOM, TRUE); //check if exist
- }
- }
- break;
- case STATE_AGENT_FALLDOWN:
- {
- if (sInstance && (mcomboBox_falls != NULL))
- {
- if (!(mcomboBox_falls->selectByValue(stranim.c_str()))) mcomboBox_falls->add(stranim.c_str(), ADD_BOTTOM, TRUE); //check if exist
- }
- }
- break;
- case STATE_AGENT_HOVER:
- {
- if (sInstance && (mcomboBox_hovers != NULL))
- {
- if (!(mcomboBox_hovers->selectByValue(stranim.c_str()))) mcomboBox_hovers->add(stranim.c_str(), ADD_BOTTOM, TRUE); //check if exist
- }
- }
- break;
- case STATE_AGENT_FLY:
- {
- if (sInstance && (mcomboBox_flys != NULL))
- {
- if (!(mcomboBox_flys->selectByValue(stranim.c_str()))) mcomboBox_flys->add(stranim.c_str(), ADD_BOTTOM, TRUE); //check if exist
- }
- }
- break;
- case STATE_AGENT_FLYSLOW:
- {
- if (sInstance && (mcomboBox_flyslows != NULL))
- {
- if (!(mcomboBox_flyslows->selectByValue(stranim.c_str()))) mcomboBox_flyslows->add(stranim.c_str(), ADD_BOTTOM, TRUE); //check if exist
- }
- }
- break;
- case STATE_AGENT_HOVER_UP:
- {
- if (sInstance && (mcomboBox_flyups != NULL))
- {
- if (!(mcomboBox_flyups->selectByValue(stranim.c_str()))) mcomboBox_flyups->add(stranim.c_str(), ADD_BOTTOM, TRUE); //check if exist
- }
- }
- break;
- case STATE_AGENT_HOVER_DOWN:
- {
- if (sInstance && (mcomboBox_flydowns != NULL))
- {
- if (!(mcomboBox_flydowns->selectByValue(stranim.c_str()))) mcomboBox_flydowns->add(stranim.c_str(), ADD_BOTTOM, TRUE); //check if exist
- }
- }
- break;
- case STATE_AGENT_LAND:
- {
- if (sInstance && (mcomboBox_lands != NULL))
- {
- if (!(mcomboBox_lands->selectByValue(stranim.c_str()))) mcomboBox_lands->add(stranim.c_str(), ADD_BOTTOM, TRUE); //check if exist
- }
- }
- break;
- case STATE_AGENT_STANDUP:
- {
- if (sInstance && (mcomboBox_standups != NULL))
- {
- if (!(mcomboBox_standups->selectByValue(stranim.c_str()))) mcomboBox_standups->add(stranim.c_str(), ADD_BOTTOM, TRUE); //check if exist
- }
- }
- break;
- case STATE_AGENT_PRE_JUMP:
- {
- if (sInstance && (mcomboBox_prejumps != NULL))
- {
- if (!(mcomboBox_prejumps->selectByValue(stranim.c_str()))) mcomboBox_prejumps->add(stranim.c_str(), ADD_BOTTOM, TRUE); //check if exist
- }
- }
- break;
+ mAOStands.push_back({ animid, stranim });
+ default: break;
}
- for (std::vector::iterator iter = mAOOverrides.begin(); iter != mAOOverrides.end(); ++iter)
+
+ if (LLComboBox* combo = getComboFromState(state))
{
- if (GetStateFromToken(strtoken.c_str()) == iter->state)
+ //LL_INFOS() << "1 anim: " << stranim.c_str() << " assetid: " << animid << LL_ENDL;
+ if (!combo->selectByValue(stranim)) //check if exist
+ combo->add(stranim, ADD_BOTTOM, true);
+ }
+
+ for (auto& ao : mAOOverrides)
+ {
+ if (state == ao.state)
{
- iter->ao_id = animid;
+ ao.ao_id = animid;
+ break;
}
}
}
@@ -1135,123 +925,14 @@ void LLFloaterAO::onNotecardLoadComplete(LLVFS *vfs,const LLUUID& asset_uuid,LLA
}
LL_INFOS() << "ao nc read sucess" << LL_ENDL;
- for (std::vector::iterator iter = mAOOverrides.begin(); iter != mAOOverrides.end(); ++iter)
+ for (auto& ao : mAOOverrides)
{
- switch(iter->state)
+ if (LLComboBox* combo = getComboFromState(ao.state))
{
-
- case STATE_AGENT_WALK:
- {
- std::string defaultanim = gSavedPerAccountSettings.getString("AODefaultWalk");
- SetDefault(mcomboBox_walks,iter->ao_id,defaultanim);
- if (getAssetIDByName(defaultanim) != LLUUID::null) iter->ao_id = getAssetIDByName(defaultanim);
- }
- break;
- case STATE_AGENT_RUN:
- {
- std::string defaultanim = gSavedPerAccountSettings.getString("AODefaultRun");
- SetDefault(mcomboBox_runs,iter->ao_id,defaultanim);
- if (getAssetIDByName(defaultanim) != LLUUID::null) iter->ao_id = getAssetIDByName(defaultanim);
- }
- break;
- case STATE_AGENT_JUMP:
- {
- std::string defaultanim = gSavedPerAccountSettings.getString("AODefaultJump");
- SetDefault(mcomboBox_jumps,iter->ao_id,defaultanim);
- if (getAssetIDByName(defaultanim) != LLUUID::null) iter->ao_id = getAssetIDByName(defaultanim);
- }
- break;
- case STATE_AGENT_SIT:
- {
- std::string defaultanim = gSavedPerAccountSettings.getString("AODefaultSit");
- SetDefault(mcomboBox_sits,iter->ao_id,defaultanim);
- if (getAssetIDByName(defaultanim) != LLUUID::null) iter->ao_id = getAssetIDByName(defaultanim);
- }
- break;
- case STATE_AGENT_CROUCH:
- {
- std::string defaultanim = gSavedPerAccountSettings.getString("AODefaultCrouch");
- SetDefault(mcomboBox_crouchs,iter->ao_id,defaultanim);
- if (getAssetIDByName(defaultanim) != LLUUID::null) iter->ao_id = getAssetIDByName(defaultanim);
- }
- break;
- case STATE_AGENT_GROUNDSIT:
- {
- std::string defaultanim = gSavedPerAccountSettings.getString("AODefaultGroundSit");
- SetDefault(mcomboBox_gsits,iter->ao_id,defaultanim);
- if (getAssetIDByName(defaultanim) != LLUUID::null) iter->ao_id = getAssetIDByName(defaultanim);
- }
- break;
- case STATE_AGENT_CROUCHWALK:
- {
- std::string defaultanim = gSavedPerAccountSettings.getString("AODefaultCrouchWalk");
- SetDefault(mcomboBox_cwalks,iter->ao_id,defaultanim);
- if (getAssetIDByName(defaultanim) != LLUUID::null) iter->ao_id = getAssetIDByName(defaultanim);
- }
- break;
- case STATE_AGENT_FALLDOWN:
- {
- std::string defaultanim = gSavedPerAccountSettings.getString("AODefaultFall");
- SetDefault(mcomboBox_falls,iter->ao_id,defaultanim);
- if (getAssetIDByName(defaultanim) != LLUUID::null) iter->ao_id = getAssetIDByName(defaultanim);
- }
- break;
- case STATE_AGENT_HOVER:
- {
- std::string defaultanim = gSavedPerAccountSettings.getString("AODefaultHover");
- SetDefault(mcomboBox_hovers,iter->ao_id,defaultanim);
- if (getAssetIDByName(defaultanim) != LLUUID::null) iter->ao_id = getAssetIDByName(defaultanim);
- }
- break;
- case STATE_AGENT_FLY:
- {
- std::string defaultanim = gSavedPerAccountSettings.getString("AODefaultFly");
- SetDefault(mcomboBox_flys,iter->ao_id,defaultanim);
- if (getAssetIDByName(defaultanim) != LLUUID::null) iter->ao_id = getAssetIDByName(defaultanim);
- }
- break;
- case STATE_AGENT_HOVER_UP:
- {
- std::string defaultanim = gSavedPerAccountSettings.getString("AODefaultFlyUp");
- SetDefault(mcomboBox_flyups,iter->ao_id,defaultanim);
- if (getAssetIDByName(defaultanim) != LLUUID::null) iter->ao_id = getAssetIDByName(defaultanim);
- }
- break;
- case STATE_AGENT_FLYSLOW:
- {
- std::string defaultanim = gSavedPerAccountSettings.getString("AODefaultFlySlow");
- SetDefault(mcomboBox_flyslows,iter->ao_id,defaultanim);
- if (getAssetIDByName(defaultanim) != LLUUID::null) iter->ao_id = getAssetIDByName(defaultanim);
- }
- break;
- case STATE_AGENT_HOVER_DOWN:
- {
- std::string defaultanim = gSavedPerAccountSettings.getString("AODefaultFlyDown");
- SetDefault(mcomboBox_flydowns,iter->ao_id,defaultanim);
- if (getAssetIDByName(defaultanim) != LLUUID::null) iter->ao_id = getAssetIDByName(defaultanim);
- }
- break;
- case STATE_AGENT_LAND:
- {
- std::string defaultanim = gSavedPerAccountSettings.getString("AODefaultLand");
- SetDefault(mcomboBox_lands,iter->ao_id,defaultanim);
- if (getAssetIDByName(defaultanim) != LLUUID::null) iter->ao_id = getAssetIDByName(defaultanim);
- }
- break;
- case STATE_AGENT_STANDUP:
- {
- std::string defaultanim = gSavedPerAccountSettings.getString("AODefaultStandUp");
- SetDefault(mcomboBox_standups,iter->ao_id,defaultanim);
- if (getAssetIDByName(defaultanim) != LLUUID::null) iter->ao_id = getAssetIDByName(defaultanim);
- }
- break;
- case STATE_AGENT_PRE_JUMP:
- {
- std::string defaultanim = gSavedPerAccountSettings.getString("AODefaultPreJump");
- SetDefault(mcomboBox_prejumps,iter->ao_id,defaultanim);
- if (getAssetIDByName(defaultanim) != LLUUID::null) iter->ao_id = getAssetIDByName(defaultanim);
- }
- break;
+ std::string defaultanim = gSavedPerAccountSettings.getString(combo->getControlName());
+ const LLUUID ao_id = getAssetIDByName(defaultanim);
+ if (ao_id != LLUUID::null) ao.ao_id = ao_id;
+ combo->selectByValue(defaultanim);
}
}
run();
@@ -1268,44 +949,14 @@ void LLFloaterAO::onNotecardLoadComplete(LLVFS *vfs,const LLUUID& asset_uuid,LLA
}
}
-BOOL LLFloaterAO::SetDefault(void* userdata, LLUUID ao_id, std::string defaultanim)
-{
- if (sInstance && (userdata))
- {
- LLComboBox *box = (LLComboBox *) userdata;
- if (ao_id.isNull())
- {
- box->clear();
- box->removeall();
- }
- else
- {
- box->selectByValue(defaultanim);
- }
- }
- return TRUE;
-}
-
class ObjectNameMatches : public LLInventoryCollectFunctor
{
public:
- ObjectNameMatches(std::string name)
- {
- sName = name;
- }
+ ObjectNameMatches(std::string name) : sName(name) {}
virtual ~ObjectNameMatches() {}
- virtual bool operator()(LLInventoryCategory* cat,
- LLInventoryItem* item)
+ virtual bool operator()(LLInventoryCategory* cat, LLInventoryItem* item)
{
- if(item)
- {
- if (item->getParentUUID() == LLFloaterAO::invfolderid)
- {
- return (item->getName() == sName);
- }
- return false;
- }
- return false;
+ return item && item->getParentUUID() == LLFloaterAO::invfolderid && item->getName() == sName;
}
private:
std::string sName;
@@ -1313,16 +964,12 @@ private:
const LLUUID& LLFloaterAO::getAssetIDByName(const std::string& name)
{
- if (name.empty() || !(LLInventoryModelBackgroundFetch::instance().isEverythingFetched())) return LLUUID::null;
+ if (name.empty() || !LLInventoryModelBackgroundFetch::instance().isEverythingFetched()) return LLUUID::null;
LLViewerInventoryCategory::cat_array_t cats;
LLViewerInventoryItem::item_array_t items;
- ObjectNameMatches objectnamematches(name);
- gInventory.collectDescendentsIf(LLUUID::null,cats,items,FALSE,objectnamematches);
+ ObjectNameMatches matches(name);
+ gInventory.collectDescendentsIf(LLUUID::null,cats,items,false, matches);
- if (items.size())
- {
- return items[0]->getAssetUUID();
- }
- return LLUUID::null;
+ return items.empty() ? LLUUID::null : items[0]->getAssetUUID();
};
diff --git a/indra/newview/floaterao.h b/indra/newview/floaterao.h
index b8a63f0da..2aaa789c9 100644
--- a/indra/newview/floaterao.h
+++ b/indra/newview/floaterao.h
@@ -8,32 +8,42 @@
#include "lleventtimer.h"
-const int STATE_AGENT_IDLE = 0;
-const int STATE_AGENT_WALK = 1;
-const int STATE_AGENT_RUN = 2;
-const int STATE_AGENT_STAND = 3;
+enum AOState
+{
+ STATE_AGENT_IDLE = 0,
+ STATE_AGENT_WALK = 1,
+ STATE_AGENT_RUN = 2,
+ STATE_AGENT_STAND = 3,
-const int STATE_AGENT_PRE_JUMP = 4;
-const int STATE_AGENT_JUMP = 5;
-const int STATE_AGENT_TURNLEFT = 6;
-const int STATE_AGENT_TURNRIGHT = 7;
+ STATE_AGENT_PRE_JUMP = 4,
+ STATE_AGENT_JUMP = 5,
+ STATE_AGENT_TURNLEFT = 6,
+ STATE_AGENT_TURNRIGHT = 7,
-const int STATE_AGENT_SIT = 8;
-const int STATE_AGENT_GROUNDSIT = 9;
+ STATE_AGENT_SIT = 8,
+ STATE_AGENT_GROUNDSIT = 9,
-const int STATE_AGENT_HOVER = 10;
-const int STATE_AGENT_HOVER_DOWN = 11;
-const int STATE_AGENT_HOVER_UP = 12;
+ STATE_AGENT_HOVER = 10,
+ STATE_AGENT_HOVER_DOWN = 11,
+ STATE_AGENT_HOVER_UP = 12,
-const int STATE_AGENT_CROUCH = 13;
-const int STATE_AGENT_CROUCHWALK = 14;
-const int STATE_AGENT_FALLDOWN = 15;
-const int STATE_AGENT_STANDUP = 16;
-const int STATE_AGENT_LAND = 17;
+ STATE_AGENT_CROUCH = 13,
+ STATE_AGENT_CROUCHWALK = 14,
+ STATE_AGENT_FALLDOWN = 15,
+ STATE_AGENT_STANDUP = 16,
+ STATE_AGENT_LAND = 17,
-const int STATE_AGENT_FLY = 18;
-const int STATE_AGENT_FLYSLOW = 19;
+ STATE_AGENT_FLY = 18,
+ STATE_AGENT_FLYSLOW = 19,
+ STATE_AGENT_TYPING = 20,
+
+ STATE_AGENT_SWIM_DOWN = 21,
+ STATE_AGENT_SWIM_UP = 22,
+ STATE_AGENT_SWIM = 23,
+ STATE_AGENT_FLOAT = 24,
+ STATE_AGENT_END
+};
@@ -43,8 +53,8 @@ class AOStandTimer : public LLEventTimer
public:
AOStandTimer();
~AOStandTimer();
- virtual BOOL tick();
- virtual void reset();
+ BOOL tick() override;
+ void reset();
};
class AOInvTimer : public LLEventTimer
@@ -52,73 +62,69 @@ class AOInvTimer : public LLEventTimer
public:
AOInvTimer();
~AOInvTimer();
- BOOL tick();
+ BOOL tick() override;
};
-class LLFloaterAO : public LLFloater
+class LLFloaterAO : public LLFloater, public LLFloaterSingleton
{
public:
- LLFloaterAO();
- virtual BOOL postBuild();
+ LLFloaterAO(const LLSD&);
+ BOOL postBuild() override;
+ void onOpen() override;
virtual ~LLFloaterAO();
- static void show(void*);
static void init();
- static void onClickToggleAO();
- static void onClickToggleSits();
static void run();
- static void updateLayout(LLFloaterAO* floater);
+ void updateLayout(bool advanced);
- static BOOL loadAnims();
+ //static bool loadAnims();
- static int getAnimationState();
- static void setAnimationState(int state);
- static void setStates(const LLUUID& id, BOOL start);
+ static void typing(bool start);
+ static AOState flyToSwimState(const AOState& state);
+ static AOState swimToFlyState(const AOState& state);
+ static AOState getAnimationState();
+ static void setAnimationState(const AOState& state);
static LLUUID getCurrentStandId();
static void setCurrentStandId(const LLUUID& id);
static int stand_iterator;
- static BOOL ChangeStand();
+ static void ChangeStand();
+ static void toggleSwim(bool underwater);
- static BOOL startMotion(const LLUUID& id, F32 time_offset = 0.f, BOOL stand = FALSE);
- static BOOL stopMotion(const LLUUID& id, BOOL stop_immediate, BOOL stand = FALSE);
+ static void doMotion(const LLUUID& id, bool start, bool stand = false);
+ static void startMotion(const LLUUID& id, bool stand = false) { doMotion(id, true, stand); }
+ static void stopMotion(const LLUUID& id, bool stand = false) { doMotion(id, false, stand); }
+ static bool swimCheck(const AOState& state);
static LLUUID GetAnimID(const LLUUID& id);
- static int GetStateFromAnimID(const LLUUID& id);
- static LLUUID GetAnimIDFromState(const int state);
- static int GetStateFromToken(std::string strtoken);
+ static AOState GetStateFromAnimID(const LLUUID& id);
+ static LLUUID GetAnimIDFromState(const AOState& state);
+ static AOState GetStateFromToken(std::string strtoken);
- static void onClickLess(void* data) ;
- static void onClickMore(void* data) ;
-
- static void onClickPrevStand(void* userdata);
- static void onClickNextStand(void* userdata);
- static void onClickReloadCard(void* userdata);
- static void onClickOpenCard(void* userdata);
- static void onClickNewCard(void* userdata);
+ static void onClickCycleStand(bool next);
+ static void onClickReloadCard();
+ static void onClickOpenCard();
+ static void onClickNewCard();
static LLUUID invfolderid;
static const LLUUID& getAssetIDByName(const std::string& name);
-
- static bool getInstance();
private:
- static LLFloaterAO* sInstance;
- static int mAnimationState;
+ static AOState mAnimationState;
static LLUUID mCurrentStandId;
- static void onSpinnerCommit(LLUICtrl* ctrl);
+ static void onSpinnerCommit();
static void onComboBoxCommit(LLUICtrl* ctrl);
- static BOOL SetDefault(void *userdata, LLUUID ao_id, std::string defaultanim);
-
- BOOL mDirty;
protected:
+ static AOState getStateFromCombo(const class LLComboBox* combo);
+ static LLComboBox* getComboFromState(const AOState& state);
+
static void onNotecardLoadComplete(LLVFS *vfs,const LLUUID& asset_uuid,LLAssetType::EType type,void* user_data, S32 status, LLExtStat ext_status);
};
diff --git a/indra/newview/floaterlocalassetbrowse.cpp b/indra/newview/floaterlocalassetbrowse.cpp
index 3c8e4fae7..5ee0445a2 100644
--- a/indra/newview/floaterlocalassetbrowse.cpp
+++ b/indra/newview/floaterlocalassetbrowse.cpp
@@ -64,6 +64,8 @@ this feature is still a work in progress.
#include "llviewermenufile.h"
#include "llfloaterimagepreview.h"
#include "llfile.h"
+#include "llsdparam.h"
+#include "llsdserialize.h"
/* including to force rebakes when needed */
#include "llvoavatarself.h"
@@ -93,21 +95,29 @@ bool LocalAssetBrowser::mSculptUpdated;
containing one loaded local texture.
*/
-LocalBitmap::LocalBitmap(std::string fullpath)
+LocalBitmap::Params::Params(const std::string& path)
+: fullpath("path", path)
+, keep_updating("update", gSavedSettings.getBOOL("LocalBitmapUpdate"))
+, type("type", TYPE_TEXTURE)
+, id("id", LLUUID::generateNewID())
{
+}
+
+LocalBitmap::LocalBitmap(const Params& p)
+{
+ llassert(!p.fullpath().empty());
valid = false;
- if ( gDirUtilp->fileExists(fullpath) )
+ if ( gDirUtilp->fileExists(p.fullpath) )
{
/* taking care of basic properties */
- id.generate();
- filename = fullpath;
- keep_updating = gSavedSettings.getBOOL("LocalBitmapUpdate");
+ id = p.id;
+ filename = p.fullpath;
+ keep_updating = p.keep_updating;
linkstatus = keep_updating ? LINK_ON : LINK_OFF;
shortname = gDirUtilp->getBaseFileName(filename, true);
- bitmap_type = TYPE_TEXTURE;
+ bitmap_type = p.type;
sculpt_dirty = false;
volume_dirty = false;
- valid = false;
/* taking care of extension type now to avoid switch madness */
std::string temp_exten = gDirUtilp->getExtension(filename);
@@ -143,6 +153,7 @@ LocalBitmap::LocalBitmap(std::string fullpath)
/* filename is valid, bitmap is decoded and valid, i can haz liftoff! */
valid = true;
+ LocalAssetBrowser::add(*this);
}
}
}
@@ -293,64 +304,64 @@ void LocalBitmap::setType( S32 type )
bitmap_type = type;
}
+void LocalBitmap::setID(const LLUUID& uuid)
+{
+ LLViewerFetchedTexture* image = gTextureList.findImage(id);
+ gTextureList.deleteImage(image);
+ id = uuid;
+ image->setID(id);
+ gTextureList.addImage(image);
+}
+
/* [information query functions] */
-std::string LocalBitmap::getShortName()
+std::string LocalBitmap::getShortName() const
{
return shortname;
}
-std::string LocalBitmap::getFileName()
+std::string LocalBitmap::getFileName() const
{
return filename;
}
-LLUUID LocalBitmap::getID()
+LLUUID LocalBitmap::getID() const
{
return id;
}
-LLSD LocalBitmap::getLastModified()
+LLSD LocalBitmap::getLastModified() const
{
return last_modified;
}
-std::string LocalBitmap::getLinkStatus()
+std::string LocalBitmap::getLinkStatus() const
{
switch(linkstatus)
{
- case LINK_ON:
- return "On";
-
- case LINK_OFF:
- return "Off";
-
- case LINK_BROKEN:
- return "Broken";
-
- case LINK_UPDATING:
- return "Updating";
-
- default:
- return "Unknown";
+ case LINK_ON: return "On";
+ case LINK_OFF: return "Off";
+ case LINK_BROKEN: return "Broken";
+ case LINK_UPDATING: return "Updating";
+ default: return "Unknown";
}
}
-bool LocalBitmap::getUpdateBool()
+bool LocalBitmap::getUpdateBool() const
{
return keep_updating;
}
-bool LocalBitmap::getIfValidBool()
+bool LocalBitmap::getIfValidBool() const
{
return valid;
}
-S32 LocalBitmap::getType()
+S32 LocalBitmap::getType() const
{
return bitmap_type;
}
-std::vector LocalBitmap::getFaceUsesThis(LLDrawable* drawable)
+std::vector LocalBitmap::getFaceUsesThis(LLDrawable* drawable) const
{
std::vector matching_faces;
@@ -365,7 +376,7 @@ std::vector LocalBitmap::getFaceUsesThis(LLDrawable* drawable)
return matching_faces;
}
-std::vector LocalBitmap::getUsingObjects(bool seek_by_type, bool seek_textures, bool seek_sculptmaps)
+std::vector LocalBitmap::getUsingObjects(bool seek_by_type, bool seek_textures, bool seek_sculptmaps) const
{
std::vector affected_vector;
@@ -413,21 +424,29 @@ std::vector LocalBitmap::getUsingObjects(bool seek_by_type, boo
return affected_vector;
}
-void LocalBitmap::getDebugInfo()
+void LocalBitmap::getDebugInfo() const
{
/* debug function: dumps everything human readable into llinfos */
- LL_INFOS() << "===[local bitmap debug]===" << "\n"
- << "path: " << filename << "\n"
- << "name: " << shortname << "\n"
- << "extension: " << extension << "\n"
- << "uuid: " << id << "\n"
- << "last modified: " << last_modified << "\n"
- << "link status: " << getLinkStatus() << "\n"
- << "keep updated: " << keep_updating << "\n"
- << "type: " << bitmap_type << "\n"
- << "is valid: " << valid << "\n"
+ LL_INFOS() << "===[local bitmap debug]===" << '\n'
+ << "path: " << filename << '\n'
+ << "name: " << shortname << '\n'
+ << "extension: " << extension << '\n'
+ << "uuid: " << id << '\n'
+ << "last modified: " << last_modified << '\n'
+ << "link status: " << getLinkStatus() << '\n'
+ << "keep updated: " << keep_updating << '\n'
+ << "type: " << bitmap_type << '\n'
+ << "is valid: " << valid << '\n'
<< "==========================" << LL_ENDL;
-
+}
+
+LLSD LocalBitmap::asLLSD() const
+{
+ return LLSD()
+ .with("path", filename)
+ .with("id", id)
+ .with("update", keep_updating)
+ .with("type", bitmap_type);
}
/*=======================================*/
@@ -439,15 +458,47 @@ void LocalBitmap::getDebugInfo()
Sits in memory until the viewer is closed.
*/
+const std::string LocalAssetBrowser::getFileName() const
+{
+ return gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "local_assets.xml");
+}
+
LocalAssetBrowser::LocalAssetBrowser()
{
+ gLocalBrowser = this;
mLayerUpdated = false;
mSculptUpdated = false;
+
+ // Load bitmaps
+ llifstream file(getFileName());
+ if (!file) return;
+ LLSD saved_assets;
+ LLSDSerialize::fromXML(saved_assets, file);
+ file.close();
+ for (auto it = saved_assets.beginArray(), end = saved_assets.endArray(); it < end; ++it)
+ {
+ const auto&& p = LLSDParamAdapter(*it);
+ LocalBitmap bm(p); // Creating one adds it to the list
+ }
+
+ if (!loaded_bitmaps.empty()) PingTimer();
}
LocalAssetBrowser::~LocalAssetBrowser()
{
-
+ // Save bitmaps
+ llofstream file(getFileName());
+ if (!file)
+ {
+ LL_WARNS() << "Could not open file " << getFileName() << " for saving." << LL_ENDL;
+ return;
+ }
+ LLSD saved_assets(LLSD::emptyArray());
+ for (const auto& bitmap : loaded_bitmaps)
+ saved_assets.append(bitmap.asLLSD());
+ LLSDSerialize::toPrettyXML(saved_assets, file);
+ file.close();
+ gLocalBrowser = nullptr;
}
void LocalAssetBrowser::AddBitmap()
@@ -463,20 +514,13 @@ void LocalAssetBrowser::AddBitmap_continued(AIFilePicker* filepicker)
return;
bool change_happened = false;
- std::vector const& filenames(filepicker->getFilenames());
- for(std::vector::const_iterator filename = filenames.begin(); filename != filenames.end(); ++filename)
- {
- LocalBitmap unit(*filename);
- if (unit.getIfValidBool())
- {
- loaded_bitmaps.push_back(unit);
+
+ for(const auto& filename : filepicker->getFilenames())
+ if (LocalBitmap(filename).getIfValidBool())
change_happened = true;
- }
- }
if (change_happened) onChangeHappened();
}
-
void LocalAssetBrowser::DelBitmap( std::vector delete_vector, S32 column )
{
bool change_happened = false;
@@ -592,21 +636,20 @@ void LocalAssetBrowser::UpdateTextureCtrlList(LLScrollListCtrl* ctrl)
if (ctrl) // checking again in case called externally for some silly reason.
{
ctrl->clearRows();
- if ( !loaded_bitmaps.empty() )
+ for (const auto& bitmap : loaded_bitmaps)
{
- for (local_list_iter iter = loaded_bitmaps.begin(); iter != loaded_bitmaps.end(); ++iter)
- {
- LLSD element;
- element["columns"][0]["column"] = "unit_name";
- element["columns"][0]["type"] = "text";
- element["columns"][0]["value"] = (*iter).shortname;
+ auto row = LLScrollListItem::Params();
+ row.columns.add(LLScrollListCell::Params()
+ .column("unit_name")
+ .type("text")
+ .value(bitmap.shortname));
- element["columns"][1]["column"] = "unit_id_HIDDEN";
- element["columns"][1]["type"] = "text";
- element["columns"][1]["value"] = (*iter).id;
+ row.columns.add(LLScrollListCell::Params()
+ .column("unit_id_HIDDEN")
+ .type("text")
+ .value(bitmap.id));
- ctrl->addElement(element);
- }
+ ctrl->addRow(row);
}
}
}
@@ -731,6 +774,11 @@ FloaterLocalAssetBrowser::FloaterLocalAssetBrowser()
// checkbox callbacks
mUpdateChkBox->setCommitCallback(boost::bind(&FloaterLocalAssetBrowser::onClickUpdateChkbox,this));
+
+ // Allow changing the ID!
+ mUUIDTxt->setCommitCallback(boost::bind(&FloaterLocalAssetBrowser::onUpdateID, this, _2));
+ mUUIDTxt->setCommitOnReturn(true);
+ mUUIDTxt->setCommitOnFocusLost(true);
}
void FloaterLocalAssetBrowser::show(void*)
@@ -798,6 +846,21 @@ void FloaterLocalAssetBrowser::onCommitTypeCombo()
}
}
+void FloaterLocalAssetBrowser::onUpdateID(const LLSD& val)
+{
+ const auto& id = val.asUUID();
+ const auto& col = mBitmapList->getFirstSelected()->getColumn(BITMAPLIST_COL_ID);
+ const auto& old_id = col->getValue().asString();
+ if (id.isNull() && id.asString() != old_id) // Just reset if invalid or unchanged
+ mUUIDTxt->setValue(old_id);
+ else
+ {
+ gLocalBrowser->GetBitmapUnit(LLUUID(old_id))->setID(id);
+ mTextureView->setImageAssetID(id);
+ col->setValue(id);
+ }
+}
+
void FloaterLocalAssetBrowser::FloaterResize(bool expand)
{
mMoreBtn->setVisible(!expand);
@@ -855,10 +918,9 @@ void FloaterLocalAssetBrowser::UpdateRightSide()
*/
if (!mTextureView->getVisible()) return;
- if (!mBitmapList->getAllSelected().empty())
+ if (const auto& selected = mBitmapList->getFirstSelected())
{
- LocalBitmap* unit = gLocalBrowser->GetBitmapUnit( LLUUID(mBitmapList->getSelectedItemLabel(BITMAPLIST_COL_ID)) );
-
+ LocalBitmap* unit = gLocalBrowser->GetBitmapUnit(LLUUID(selected->getColumn(BITMAPLIST_COL_ID)->getValue().asString()));
if ( unit )
{
mTextureView->setImageAssetID(unit->getID());
@@ -873,6 +935,7 @@ void FloaterLocalAssetBrowser::UpdateRightSide()
mTextureView->setEnabled(true);
mUpdateChkBox->setEnabled(true);
mTypeComboBox->setEnabled(true);
+ mUUIDTxt->setEnabled(true);
}
}
else
@@ -884,12 +947,14 @@ void FloaterLocalAssetBrowser::UpdateRightSide()
mTypeComboBox->selectFirstItem();
mTypeComboBox->setEnabled(false);
+ mUUIDTxt->setEnabled(false);
- mPathTxt->setText(LLStringExplicit("None"));
- mUUIDTxt->setText(LLStringExplicit("None"));
- mNameTxt->setText(LLStringExplicit("None"));
- mLinkTxt->setText(LLStringExplicit("None"));
- mTimeTxt->setText(LLStringExplicit("None"));
+ const auto none = LLStringExplicit("None");
+ mPathTxt->setText(none);
+ mUUIDTxt->setText(none);
+ mNameTxt->setText(none);
+ mLinkTxt->setText(none);
+ mTimeTxt->setText(none);
}
}
@@ -931,7 +996,7 @@ void LocalAssetBrowserTimer::stop()
mEventTimer.stop();
}
-bool LocalAssetBrowserTimer::isRunning()
+bool LocalAssetBrowserTimer::isRunning() const
{
return mEventTimer.getStarted();
}
diff --git a/indra/newview/floaterlocalassetbrowse.h b/indra/newview/floaterlocalassetbrowse.h
index dd7e618ea..290fbe4e3 100644
--- a/indra/newview/floaterlocalassetbrowse.h
+++ b/indra/newview/floaterlocalassetbrowse.h
@@ -97,7 +97,15 @@ struct affected_object
class LocalBitmap
{
public:
- LocalBitmap(std::string filename);
+ struct Params : public LLInitParam::Block
+ {
+ Mandatory fullpath;
+ Optional keep_updating;
+ Optional type;
+ Optional id;
+ Params(const std::string& path = LLStringUtil::null);
+ };
+ LocalBitmap(const Params& p);
virtual ~LocalBitmap();
friend class LocalAssetBrowser;
@@ -127,25 +135,28 @@ class LocalBitmap
};
public: /* [information query functions] */
- std::string getShortName();
- std::string getFileName();
- LLUUID getID();
- LLSD getLastModified();
- std::string getLinkStatus();
- bool getUpdateBool();
+ std::string getShortName() const;
+ std::string getFileName() const;
+ LLUUID getID() const;
+ void setID(const LLUUID&);
+ LLSD getLastModified() const;
+ std::string getLinkStatus() const;
+ bool getUpdateBool() const;
void setType( S32 );
- bool getIfValidBool();
- S32 getType();
- void getDebugInfo();
+ bool getIfValidBool() const;
+ S32 getType() const;
+ void getDebugInfo() const;
+ LLSD asLLSD() const;
+
private: /* [maintenence functions] */
void updateSelf();
bool decodeSelf(LLImageRaw* rawimg);
void setUpdateBool();
- std::vector getFaceUsesThis(LLDrawable*);
+ std::vector getFaceUsesThis(LLDrawable*) const;
std::vector getUsingObjects(bool seek_by_type = true,
- bool seek_textures = false, bool seek_sculptmaps = false);
+ bool seek_textures = false, bool seek_sculptmaps = false) const;
protected: /* [basic properties] */
std::string shortname;
@@ -173,9 +184,10 @@ class LocalBitmap
class AIFilePicker;
-class LocalAssetBrowser
+class LocalAssetBrowser : public LLSingleton
{
public:
+ const std::string getFileName() const;
LocalAssetBrowser();
virtual ~LocalAssetBrowser();
friend class FloaterLocalAssetBrowser;
@@ -183,6 +195,7 @@ class LocalAssetBrowser
static void UpdateTextureCtrlList(LLScrollListCtrl*);
static void setLayerUpdated(bool toggle) { mLayerUpdated = toggle; }
static void setSculptUpdated(bool toggle) { mSculptUpdated = toggle; }
+ static void add(const LocalBitmap& unit) { loaded_bitmaps.push_back(unit); }
static void AddBitmap();
static void AddBitmap_continued(AIFilePicker* filepicker);
static void DelBitmap( std::vector, S32 column = BITMAPLIST_COL_ID );
@@ -241,6 +254,8 @@ private:
// Combobox type select
void onCommitTypeCombo();
+ void onUpdateID(const LLSD& val);
+
// Widgets
LLButton* mAddBtn;
LLButton* mDelBtn;
@@ -289,10 +304,10 @@ class LocalAssetBrowserTimer : public LLEventTimer
public:
LocalAssetBrowserTimer();
~LocalAssetBrowserTimer();
- virtual BOOL tick();
+ BOOL tick() override;
void start();
void stop();
- bool isRunning();
+ bool isRunning() const;
};
#endif
diff --git a/indra/newview/hippogridmanager.cpp b/indra/newview/hippogridmanager.cpp
index 5295aac95..315b7cf8b 100644
--- a/indra/newview/hippogridmanager.cpp
+++ b/indra/newview/hippogridmanager.cpp
@@ -48,6 +48,7 @@ HippoGridInfo::HippoGridInfo(const std::string& gridName) :
mWebSite(LLStringUtil::null),
mSupportUrl(LLStringUtil::null),
mRegisterUrl(LLStringUtil::null),
+ mPartnerUrl(LLStringUtil::null),
mPasswordUrl(LLStringUtil::null),
mSearchUrl(LLStringUtil::null),
mGridMessage(""),
@@ -81,7 +82,7 @@ const std::string& HippoGridInfo::getGridOwner() const
}
else
{
- return this->getGridName();
+ return getGridName();
}
}
@@ -102,12 +103,11 @@ void HippoGridInfo::setPlatform(Platform platform)
void HippoGridInfo::setPlatform(const std::string& platform)
{
std::string tmp = platform;
- for (unsigned i=0; imXmlState = XML_SUPPORT;
else if ((strcasecmp(name, "register") == 0) || (strcasecmp(name, "account") == 0))
self->mXmlState = XML_REGISTER;
+ else if (strcasecmp(name, "partner") == 0)
+ self->mXmlState = XML_PARTNER;
else if (strcasecmp(name, "password") == 0)
self->mXmlState = XML_PASSWORD;
else if (strcasecmp(name, "search") == 0)
@@ -337,7 +344,7 @@ void HippoGridInfo::onXmlCharacterData(void* userData, const XML_Char* s, int le
case XML_GRIDNAME:
{
- if (self->mGridName == "")
+ if (self->mGridName.empty())
{
self->mGridName.assign(s, len);
}
@@ -348,6 +355,7 @@ void HippoGridInfo::onXmlCharacterData(void* userData, const XML_Char* s, int le
case XML_WEBSITE: self->mWebSite.assign(s, len); break;
case XML_SUPPORT: self->mSupportUrl.assign(s, len); break;
case XML_REGISTER: self->mRegisterUrl.assign(s, len); break;
+ case XML_PARTNER: self->mPartnerUrl.assign(s, len); break;
case XML_PASSWORD: self->mPasswordUrl.assign(s, len); break;
case XML_MESSAGE: self->mGridMessage.assign(s, len); break;
@@ -366,7 +374,7 @@ void HippoGridInfo::getGridInfo()
// Make sure the uri ends on a '/'.
std::string uri = mLoginUri;
- if (uri.compare(uri.length() - 1, 1, "/") != 0)
+ if (uri.back() != '/')
{
uri += '/';
}
@@ -482,9 +490,9 @@ std::string HippoGridInfo::getGridNick() const
// static
const char* HippoGridInfo::getPlatformString(Platform platform)
{
- static const char* platformStrings[PLATFORM_LAST] =
+ constexpr const char* platformStrings[PLATFORM_LAST] =
{
- "Other", "Aurora", "OpenSim", "SecondLife"
+ "Other", "WhiteCore", "OpenSim", "SecondLife"
};
if ((platform < PLATFORM_OTHER) || (platform >= PLATFORM_LAST))
@@ -894,6 +902,7 @@ void HippoGridManager::parseData(LLSD &gridInfo, bool mergeIfNewer)
if (gridMap.has("website")) grid->setWebSite(gridMap["website"]);
if (gridMap.has("support")) grid->setSupportUrl(gridMap["support"]);
if (gridMap.has("register")) grid->setRegisterUrl(gridMap["register"]);
+ if (gridMap.has("partner")) grid->setPartnerUrl(gridMap["partner"]);
if (gridMap.has("password")) grid->setPasswordUrl(gridMap["password"]);
if (gridMap.has("search")) grid->setSearchUrl(gridMap["search"]);
if (gridMap.has("render_compat")) grid->setRenderCompat(gridMap["render_compat"]);
@@ -929,6 +938,7 @@ void HippoGridManager::saveFile()
gridInfo[i]["website"] = grid->getWebSite();
gridInfo[i]["support"] = grid->getSupportUrl();
gridInfo[i]["register"] = grid->getRegisterUrl();
+ gridInfo[i]["partner"] = grid->getPartnerUrl();
gridInfo[i]["password"] = grid->getPasswordUrl();
gridInfo[i]["search"] = grid->getSearchUrl();
diff --git a/indra/newview/hippogridmanager.h b/indra/newview/hippogridmanager.h
index 450cc35f7..8d2ae9650 100644
--- a/indra/newview/hippogridmanager.h
+++ b/indra/newview/hippogridmanager.h
@@ -26,7 +26,7 @@ class HippoGridInfo
public:
enum Platform {
PLATFORM_OTHER = 0,
- PLATFORM_AURORA,
+ PLATFORM_WHITECORE,
PLATFORM_OPENSIM,
PLATFORM_SECONDLIFE,
PLATFORM_LAST
@@ -35,8 +35,8 @@ public:
explicit HippoGridInfo(const std::string& gridName);
Platform getPlatform() { return mPlatform; }
- bool isOpenSimulator() const { return (mPlatform == PLATFORM_OPENSIM || mPlatform == PLATFORM_AURORA); }
- bool isAurora() const { return (mPlatform == PLATFORM_AURORA); }
+ bool isOpenSimulator() const { return (mPlatform == PLATFORM_OPENSIM || mPlatform == PLATFORM_WHITECORE); }
+ bool isWhiteCore() const { return (mPlatform == PLATFORM_WHITECORE); }
bool isSecondLife() const { return (mPlatform == PLATFORM_SECONDLIFE); }
bool isAvination() const { return mIsInAvination; }
bool isInProductionGrid() const { llassert(mPlatform == PLATFORM_SECONDLIFE); return mIsInProductionGrid; } // Should only be called if isSecondLife() returns true.
@@ -48,6 +48,7 @@ public:
const std::string& getWebSite() const { return mWebSite; }
const std::string& getSupportUrl() const { return mSupportUrl; }
const std::string& getRegisterUrl() const { return mRegisterUrl; }
+ const std::string& getPartnerUrl() const { return mPartnerUrl; }
const std::string& getPasswordUrl() const { return mPasswordUrl; }
// Returns the url base used for the Web Search tab
const std::string& getSearchUrl() const { return mSearchUrl; }
@@ -75,6 +76,7 @@ public:
void setWebSite (const std::string& website);
void setSupportUrl(const std::string& url);
void setRegisterUrl(const std::string& url);
+ void setPartnerUrl(const std::string& url);
void setPasswordUrl(const std::string& url);
// sets the url base used for the Web Search tab
void setSearchUrl(const std::string& url);
@@ -111,6 +113,7 @@ private:
std::string mWebSite;
std::string mSupportUrl;
std::string mRegisterUrl;
+ std::string mPartnerUrl;
std::string mPasswordUrl;
std::string mSearchUrl;
std::string mVoiceConnector;
@@ -134,7 +137,7 @@ private:
{
XML_VOID, XML_PLATFORM, XML_GRIDNAME, XML_GRIDNICK,
XML_LOGINURI, XML_LOGINPAGE, XML_HELPERURI,
- XML_WEBSITE, XML_SUPPORT, XML_REGISTER, XML_PASSWORD, XML_SEARCH, XML_MESSAGE
+ XML_WEBSITE, XML_SUPPORT, XML_REGISTER, XML_PARTNER, XML_PASSWORD, XML_SEARCH, XML_MESSAGE
};
XmlState mXmlState;
diff --git a/indra/newview/hippolimits.cpp b/indra/newview/hippolimits.cpp
index 8e7462511..439af0157 100644
--- a/indra/newview/hippolimits.cpp
+++ b/indra/newview/hippolimits.cpp
@@ -21,8 +21,8 @@ void HippoLimits::setLimits()
{
if (gHippoGridManager->getConnectedGrid()->getPlatform() == HippoGridInfo::PLATFORM_SECONDLIFE) {
setSecondLifeLimits();
- } else if (gHippoGridManager->getConnectedGrid()->getPlatform() == HippoGridInfo::PLATFORM_AURORA) {
- setAuroraLimits();
+ } else if (gHippoGridManager->getConnectedGrid()->getPlatform() == HippoGridInfo::PLATFORM_WHITECORE) {
+ setWhiteCoreLimits();
} else {
setOpenSimLimits();
}
@@ -53,20 +53,19 @@ void HippoLimits::setOpenSimLimits()
setMaxAgentGroups();
mMaxPrimScale = 8192.0f;
mMaxHeight = 10000.0f;
+ mMinPrimScale = 0.001f;
if (gHippoGridManager->getConnectedGrid()->isRenderCompat()) {
LL_INFOS() << "Using rendering compatible OpenSim limits." << LL_ENDL;
- mMinPrimScale = 0.01f;
mMinHoleSize = 0.05f;
mMaxHollow = 0.95f;
} else {
LL_INFOS() << "Using Hippo OpenSim limits." << LL_ENDL;
- mMinPrimScale = 0.001f;
mMinHoleSize = 0.01f;
mMaxHollow = 0.99f;
}
}
-void HippoLimits::setAuroraLimits()
+void HippoLimits::setWhiteCoreLimits()
{
setMaxAgentGroups();
mMaxPrimScale = 8192.0f;
diff --git a/indra/newview/hippolimits.h b/indra/newview/hippolimits.h
index 0c119cd34..6c48fc298 100644
--- a/indra/newview/hippolimits.h
+++ b/indra/newview/hippolimits.h
@@ -27,7 +27,7 @@ private:
void setMaxAgentGroups();
void setOpenSimLimits();
- void setAuroraLimits();
+ void setWhiteCoreLimits();
void setSecondLifeLimits();
};
diff --git a/indra/newview/hippopanelgrids.cpp b/indra/newview/hippopanelgrids.cpp
index d5570e84a..53446f17c 100644
--- a/indra/newview/hippopanelgrids.cpp
+++ b/indra/newview/hippopanelgrids.cpp
@@ -130,6 +130,7 @@ BOOL HippoPanelGridsImpl::postBuild()
requires("website");
requires("support");
requires("register");
+ requires("partner");
requires("password");
requires("search");
requires("btn_delete");
@@ -172,7 +173,7 @@ void HippoPanelGridsImpl::refresh()
LLComboBox *grids = getChild("grid_selector");
S32 selectIndex = -1, i = 0;
grids->removeall();
- if (defaultGrid != "") {
+ if (!defaultGrid.empty()) {
grids->add(defaultGrid);
selectIndex = i++;
}
@@ -192,10 +193,10 @@ void HippoPanelGridsImpl::refresh()
if (selectIndex >= 0) {
grids->setCurrentByIndex(selectIndex);
} else {
- grids->setLabel(LLStringExplicit("")); // LLComboBox::removeall() does not clear the label
+ grids->setLabel(LLStringUtil::null); // LLComboBox::removeall() does not clear the label
}
- childSetTextArg("default_grid", "[DEFAULT]", (defaultGrid != "")? defaultGrid: " ");
+ childSetTextArg("default_grid", "[DEFAULT]", !defaultGrid.empty() ? defaultGrid : " ");
childSetEnabled("btn_delete", (selectIndex >= 0) && mIsEditable );
childSetEnabled("btn_copy", (mState == NORMAL) && (selectIndex >= 0));
@@ -244,11 +245,12 @@ void HippoPanelGridsImpl::loadCurGrid()
childSetText("support", gridInfo->getSupportUrl());
childSetText("search", gridInfo->getSearchUrl());
childSetText("register", gridInfo->getRegisterUrl());
+ childSetText("partner", gridInfo->getPartnerUrl());
childSetText("password", gridInfo->getPasswordUrl());
childSetValue("render_compat", gridInfo->isRenderCompat());
enableEditing(!gridInfo->getLocked());
} else {
- std::string empty = "";
+ const std::string& empty = LLStringUtil::null;
LLComboBox *platform = getChild("platform");
if (platform) platform->setCurrentByIndex(HippoGridInfo::PLATFORM_OTHER);
childSetText("gridname", empty);
@@ -259,6 +261,7 @@ void HippoPanelGridsImpl::loadCurGrid()
childSetText("support", empty);
childSetText("search", empty);
childSetText("register", empty);
+ childSetText("partner", empty);
childSetText("password", empty);
childSetValue("render_compat", true);
enableEditing(true);
@@ -288,9 +291,9 @@ bool HippoPanelGridsImpl::saveCurGrid()
refresh();
std::string gridname = childGetValue("gridname");
- if (gridname == "") gridname = "";
+ if (gridname == "") gridname.clear();
std::string loginuri = childGetValue("loginuri");
- if (loginuri == "") loginuri = "";
+ if (loginuri == "") loginuri.clear();
if (gridname.empty() && !loginuri.empty())
this->retrieveGridInfo();
@@ -299,8 +302,8 @@ bool HippoPanelGridsImpl::saveCurGrid()
// check nickname
std::string gridname = childGetValue("gridname");
- childSetValue("gridname", (gridname != "")? gridname: "");
- if (gridname == "") {
+ childSetValue("gridname", !gridname.empty() ? gridname : "");
+ if (gridname.empty()) {
LLNotificationsUtil::add("GridsNoNick");
return false;
}
@@ -312,7 +315,7 @@ bool HippoPanelGridsImpl::saveCurGrid()
}
// check login URI
- if (loginuri == "") {
+ if (loginuri.empty()) {
LLSD args;
args["NAME"] = gridname;
LLNotificationsUtil::add("GridsNoLoginUri", args);
@@ -361,6 +364,7 @@ bool HippoPanelGridsImpl::saveCurGrid()
gridInfo->setWebSite(childGetValue("website"));
gridInfo->setSupportUrl(childGetValue("support"));
gridInfo->setRegisterUrl(childGetValue("register"));
+ gridInfo->setPartnerUrl(childGetValue("partner"));
gridInfo->setPasswordUrl(childGetValue("password"));
gridInfo->setSearchUrl(childGetValue("search"));
gridInfo->setRenderCompat(childGetValue("render_compat"));
@@ -384,7 +388,7 @@ void HippoPanelGridsImpl::reset()
void HippoPanelGridsImpl::retrieveGridInfo()
{
std::string loginuri = childGetValue("loginuri");
- if ((loginuri == "") || (loginuri == "")) {
+ if ((loginuri.empty()) || (loginuri == "")) {
LLNotificationsUtil::add("GridInfoNoLoginUri");
return;
}
@@ -394,7 +398,7 @@ void HippoPanelGridsImpl::retrieveGridInfo()
if (mState == NORMAL) {
grid = gHippoGridManager->getGrid(mCurGrid);
} else if ((mState == ADD_NEW) || (mState == ADD_COPY)) {
- grid = new HippoGridInfo("");
+ grid = new HippoGridInfo(LLStringUtil::null);
cleanupGrid = true;
} else {
LL_ERRS() << "Illegal state " << mState << '.' << LL_ENDL;
@@ -412,16 +416,17 @@ void HippoPanelGridsImpl::retrieveGridInfo()
if (grid->getPlatform() != HippoGridInfo::PLATFORM_OTHER)
getChild("platform")->setCurrentByIndex(grid->getPlatform());
- if (grid->getGridName() != "") childSetText("gridname", grid->getGridName());
- if (grid->getLoginUri() != "") childSetText("loginuri", grid->getLoginUri());
- if (grid->getLoginPage() != "") childSetText("loginpage", grid->getLoginPage());
- if (grid->getHelperUri() != "") childSetText("helperuri", grid->getHelperUri());
- if (grid->getWebSite() != "") childSetText("website", grid->getWebSite());
- if (grid->getSupportUrl() != "") childSetText("support", grid->getSupportUrl());
- if (grid->getRegisterUrl() != "") childSetText("register", grid->getRegisterUrl());
- if (grid->getPasswordUrl() != "") childSetText("password", grid->getPasswordUrl());
- if (grid->getSearchUrl() != "") childSetText("search", grid->getSearchUrl());
- if (grid->getGridMessage() != "") childSetText("gridmessage", grid->getGridMessage());
+ if (!grid->getGridName().empty()) childSetText("gridname", grid->getGridName());
+ if (!grid->getLoginUri().empty()) childSetText("loginuri", grid->getLoginUri());
+ if (!grid->getLoginPage().empty()) childSetText("loginpage", grid->getLoginPage());
+ if (!grid->getHelperUri().empty()) childSetText("helperuri", grid->getHelperUri());
+ if (!grid->getWebSite().empty()) childSetText("website", grid->getWebSite());
+ if (!grid->getSupportUrl().empty()) childSetText("support", grid->getSupportUrl());
+ if (!grid->getRegisterUrl().empty()) childSetText("register", grid->getRegisterUrl());
+ if (!grid->getPartnerUrl().empty()) childSetText("partner", grid->getPartnerUrl());
+ if (!grid->getPasswordUrl().empty()) childSetText("password", grid->getPasswordUrl());
+ if (!grid->getSearchUrl().empty()) childSetText("search", grid->getSearchUrl());
+ if (!grid->getGridMessage().empty()) childSetText("gridmessage", grid->getGridMessage());
}
catch(AIAlert::ErrorCode const& error)
{
@@ -532,6 +537,8 @@ void HippoPanelGridsImpl::onClickAdvanced(void *data)
self->childSetVisible("support", false);
self->childSetVisible("register_label", false);
self->childSetVisible("register", false);
+ self->childSetVisible("partner_label", false);
+ self->childSetVisible("partner", false);
self->childSetVisible("password_label", false);
self->childSetVisible("password", false);
self->childSetVisible("search_label", false);
@@ -551,6 +558,8 @@ void HippoPanelGridsImpl::onClickAdvanced(void *data)
self->childSetVisible("support", true);
self->childSetVisible("register_label", true);
self->childSetVisible("register", true);
+ self->childSetVisible("partner_label", true);
+ self->childSetVisible("partner", true);
self->childSetVisible("password_label", true);
self->childSetVisible("password", true);
self->childSetVisible("search_label", true);
@@ -578,6 +587,7 @@ void HippoPanelGridsImpl::enableEditing(bool b)
"website",
"support",
"register",
+ "partner",
"password",
"search",
"btn_delete",
diff --git a/indra/newview/icons/alpha/viewer.png b/indra/newview/icons/alpha/viewer.png
index 3e4c44fe5..8d7619f95 100644
Binary files a/indra/newview/icons/alpha/viewer.png and b/indra/newview/icons/alpha/viewer.png differ
diff --git a/indra/newview/installers/darwin/firstlook-dmg/background.jpg b/indra/newview/installers/darwin/firstlook-dmg/background.jpg
index 55294dcc9..3962e2fb3 100644
Binary files a/indra/newview/installers/darwin/firstlook-dmg/background.jpg and b/indra/newview/installers/darwin/firstlook-dmg/background.jpg differ
diff --git a/indra/newview/installers/darwin/publicnightly-dmg/background.jpg b/indra/newview/installers/darwin/publicnightly-dmg/background.jpg
index 55294dcc9..3962e2fb3 100644
Binary files a/indra/newview/installers/darwin/publicnightly-dmg/background.jpg and b/indra/newview/installers/darwin/publicnightly-dmg/background.jpg differ
diff --git a/indra/newview/installers/darwin/release-dmg/background.jpg b/indra/newview/installers/darwin/release-dmg/background.jpg
index 55294dcc9..3962e2fb3 100644
Binary files a/indra/newview/installers/darwin/release-dmg/background.jpg and b/indra/newview/installers/darwin/release-dmg/background.jpg differ
diff --git a/indra/newview/installers/darwin/releasecandidate-dmg/background.jpg b/indra/newview/installers/darwin/releasecandidate-dmg/background.jpg
index 55294dcc9..3962e2fb3 100644
Binary files a/indra/newview/installers/darwin/releasecandidate-dmg/background.jpg and b/indra/newview/installers/darwin/releasecandidate-dmg/background.jpg differ
diff --git a/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi
index ed160f8a1..8ff723f76 100644
--- a/indra/newview/installers/windows/installer_template.nsi
+++ b/indra/newview/installers/windows/installer_template.nsi
@@ -24,6 +24,10 @@
;;
;; Author: James Cook, Don Kjer, Callum Prentice, Drake Arconis
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;--------------------------------
+;Unicode
+ Unicode true
+
;--------------------------------
;Include Modern UI
@@ -72,7 +76,7 @@
InstallDirRegKey HKLM "SOFTWARE\${VENDORSTR}\${APPNAMEONEWORD}" ""
!endif
- ;Request application privileges for Windows Vista
+ ;Request application privileges for Windows UAC
RequestExecutionLevel admin
;Compression
@@ -139,7 +143,11 @@
!define MUI_STARTMENUPAGE_REGISTRY_KEY "SOFTWARE\${VENDORSTR}\${APPNAMEONEWORD}"
!define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "Start Menu Folder"
!define MUI_PAGE_CUSTOMFUNCTION_PRE check_skip
+!ifdef WIN64_BIN_BUILD
!define MUI_STARTMENUPAGE_DEFAULTFOLDER "${APPNAME} (64 bit) Viewer"
+!else
+ !define MUI_STARTMENUPAGE_DEFAULTFOLDER "${APPNAME} Viewer"
+!endif
!insertmacro MUI_PAGE_STARTMENU Application $STARTMENUFOLDER
;Install Progress Page
@@ -150,6 +158,10 @@
!define MUI_PAGE_CUSTOMFUNCTION_PRE check_skip_finish
!define MUI_FINISHPAGE_RUN
!define MUI_FINISHPAGE_RUN_FUNCTION launch_viewer
+ !define MUI_FINISHPAGE_SHOWREADME
+ !define MUI_FINISHPAGE_SHOWREADME_TEXT "Create Desktop Shortcut"
+ !define MUI_FINISHPAGE_SHOWREADME_NOTCHECKED
+ !define MUI_FINISHPAGE_SHOWREADME_FUNCTION create_desktop_shortcut
!define MUI_FINISHPAGE_NOREBOOTSUPPORT
!insertmacro MUI_PAGE_FINISH
@@ -185,12 +197,12 @@
;because this will make your installer start faster.
!insertmacro MUI_RESERVEFILE_LANGDLL
- ReserveFile "${NSISDIR}\Plugins\NSISdl.dll"
- ReserveFile "${NSISDIR}\Plugins\nsDialogs.dll"
- ReserveFile "${NSISDIR}\Plugins\StartMenu.dll"
- ReserveFile "${NSISDIR}\Plugins\StdUtils.dll"
- ReserveFile "${NSISDIR}\Plugins\System.dll"
- ReserveFile "${NSISDIR}\Plugins\UserInfo.dll"
+ ReserveFile "${NSISDIR}\Plugins\x86-unicode\NSISdl.dll"
+ ReserveFile "${NSISDIR}\Plugins\x86-unicode\nsDialogs.dll"
+ ReserveFile "${NSISDIR}\Plugins\x86-unicode\StartMenu.dll"
+ ReserveFile "${NSISDIR}\Plugins\x86-unicode\StdUtils.dll"
+ ReserveFile "${NSISDIR}\Plugins\x86-unicode\System.dll"
+ ReserveFile "${NSISDIR}\Plugins\x86-unicode\UserInfo.dll"
;--------------------------------
; Local Functions
@@ -212,6 +224,14 @@ Function launch_viewer
${StdUtils.ExecShellAsUser} $0 "$INSTDIR\$INSTEXE" "open" "$SHORTCUT_LANG_PARAM"
FunctionEnd
+Function create_desktop_shortcut
+!ifdef WIN64_BIN_BUILD
+ CreateShortCut "$DESKTOP\$INSTSHORTCUT x64.lnk" "$INSTDIR\$INSTEXE" "$SHORTCUT_LANG_PARAM" "$INSTDIR\$INSTEXE"
+!else
+ CreateShortCut "$DESKTOP\$INSTSHORTCUT.lnk" "$INSTDIR\$INSTEXE" "$SHORTCUT_LANG_PARAM" "$INSTDIR\$INSTEXE"
+!endif
+FunctionEnd
+
;Check version compatibility
Function CheckWindowsVersion
!ifdef WIN64_BIN_BUILD
@@ -221,7 +241,7 @@ Function CheckWindowsVersion
${EndIf}
!endif
- ${If} ${AtMostWinXP}
+ ${If} ${AtMostWinVista}
MessageBox MB_OK $(CheckWindowsVersionMB)
Quit
${EndIf}
@@ -229,20 +249,6 @@ FunctionEnd
;Check service pack compatibility and suggest upgrade
Function CheckWindowsServPack
- ${If} ${IsWinVista}
- ${AndIfNot} ${IsServicePack} 2
- MessageBox MB_OK $(CheckWindowsServPackMB)
- DetailPrint $(UseLatestServPackDP)
- Return
- ${EndIf}
-
- ${If} ${IsWin2008}
- ${AndIfNot} ${IsServicePack} 2
- MessageBox MB_OK $(CheckWindowsServPackMB)
- DetailPrint $(UseLatestServPackDP)
- Return
- ${EndIf}
-
${If} ${IsWin7}
${AndIfNot} ${IsServicePack} 1
MessageBox MB_OK $(CheckWindowsServPackMB)
@@ -321,6 +327,8 @@ Function CloseSecondLife
StrCmp $SKIP_DIALOGS "true" CLOSE
MessageBox MB_YESNOCANCEL $(CloseSecondLifeInstMB) IDYES CLOSE IDNO DONE
+
+; CANCEL_INSTALL:
Quit
CLOSE:
@@ -346,7 +354,9 @@ Function un.CloseSecondLife
Push $0
FindWindow $0 "Second Life" ""
IntCmp $0 0 DONE
- MessageBox MB_YESNOCANCEL $(CloseSecondLifeUnInstMB) IDYES CLOSE IDNO DONE
+ MessageBox MB_OKCANCEL $(CloseSecondLifeUnInstMB) IDOK CLOSE IDCANCEL CANCEL_UNINSTALL
+
+ CANCEL_UNINSTALL:
Quit
CLOSE:
@@ -491,18 +501,46 @@ Section "Viewer"
;Write URL registry info
- WriteRegStr HKEY_CLASSES_ROOT "${URLNAME}" "(Default)" "URL:Second Life"
+ DeleteRegKey HKEY_CLASSES_ROOT "${URLNAME}"
+ WriteRegStr HKEY_CLASSES_ROOT "${URLNAME}" "" "URL:Second Life"
WriteRegStr HKEY_CLASSES_ROOT "${URLNAME}" "URL Protocol" ""
WriteRegStr HKEY_CLASSES_ROOT "${URLNAME}\DefaultIcon" "" "$INSTDIR\$INSTEXE"
;; URL param must be last item passed to viewer, it ignores subsequent params
;; to avoid parameter injection attacks.
+ WriteRegStr HKEY_CLASSES_ROOT "${URLNAME}\shell" "" "open"
+!ifdef WIN64_BIN_BUILD
+ WriteRegStr HKEY_CLASSES_ROOT "${URLNAME}\shell\open" "FriendlyAppName" "$INSTSHORTCUT (64 bit) Viewer"
+!else
+ WriteRegStr HKEY_CLASSES_ROOT "${URLNAME}\shell\open" "FriendlyAppName" "$INSTSHORTCUT Viewer"
+!endif
WriteRegExpandStr HKEY_CLASSES_ROOT "${URLNAME}\shell\open\command" "" "$\"$INSTDIR\$INSTEXE$\" -url $\"%1$\""
- WriteRegStr HKEY_CLASSES_ROOT "x-grid-location-info" "(Default)" "URL:Second Life"
+ DeleteRegKey HKEY_CLASSES_ROOT "x-grid-info"
+ WriteRegStr HKEY_CLASSES_ROOT "x-grid-info" "" "URL:Hypergrid"
+ WriteRegStr HKEY_CLASSES_ROOT "x-grid-info" "URL Protocol" ""
+ WriteRegStr HKEY_CLASSES_ROOT "x-grid-info\DefaultIcon" "" "$INSTDIR\$INSTEXE"
+ ;; URL param must be last item passed to viewer, it ignores subsequent params
+ ;; to avoid parameter injection attacks.
+ WriteRegStr HKEY_CLASSES_ROOT "x-grid-info\shell" "" "open"
+!ifdef WIN64_BIN_BUILD
+ WriteRegStr HKEY_CLASSES_ROOT "x-grid-info\shell\open" "FriendlyAppName" "$INSTSHORTCUT (64 bit) Viewer"
+!else
+ WriteRegStr HKEY_CLASSES_ROOT "x-grid-info\shell\open" "FriendlyAppName" "$INSTSHORTCUT Viewer"
+!endif
+ WriteRegExpandStr HKEY_CLASSES_ROOT "x-grid-info\shell\open\command" "" "$\"$INSTDIR\$INSTEXE$\" -url $\"%1$\""
+
+ DeleteRegKey HKEY_CLASSES_ROOT "x-grid-location-info"
+ WriteRegStr HKEY_CLASSES_ROOT "x-grid-location-info" "" "URL:Hypergrid legacy"
WriteRegStr HKEY_CLASSES_ROOT "x-grid-location-info" "URL Protocol" ""
WriteRegStr HKEY_CLASSES_ROOT "x-grid-location-info\DefaultIcon" "" "$\"$INSTDIR\$INSTEXE$\""
;; URL param must be last item passed to viewer, it ignores subsequent params
;; to avoid parameter injection attacks.
+ WriteRegStr HKEY_CLASSES_ROOT "x-grid-location-info\shell" "" "open"
+!ifdef WIN64_BIN_BUILD
+ WriteRegStr HKEY_CLASSES_ROOT "x-grid-location-info\shell\open" "FriendlyAppName" "$INSTSHORTCUT (64 bit) Viewer"
+!else
+ WriteRegStr HKEY_CLASSES_ROOT "x-grid-location-info\shell\open" "FriendlyAppName" "$INSTSHORTCUT Viewer"
+!endif
WriteRegExpandStr HKEY_CLASSES_ROOT "x-grid-location-info\shell\open\command" "" "$\"$INSTDIR\$INSTEXE$\" -url $\"%1$\""
;Create uninstaller
diff --git a/indra/newview/lffloaterinvpanel.cpp b/indra/newview/lffloaterinvpanel.cpp
index 5fde1fa10..2578c90a2 100644
--- a/indra/newview/lffloaterinvpanel.cpp
+++ b/indra/newview/lffloaterinvpanel.cpp
@@ -32,7 +32,7 @@ LFFloaterInvPanel::LFFloaterInvPanel(const LLUUID& cat_id, LLInventoryModel* mod
mCommitCallbackRegistrar.add("InvPanel.Search", boost::bind(&LLInventoryPanel::setFilterSubString, boost::ref(mPanel), _2));
LLUICtrlFactory::getInstance()->buildFloater(this, "floater_inv_panel.xml");
LLPanel* panel = getChild("placeholder_panel");
- mPanel = new LLInventoryPanel("inv_panel", LLInventoryPanel::DEFAULT_SORT_ORDER, cat_id.asString(), panel->getRect(), model, true);
+ mPanel = new LLInventoryPanel("inv_panel", LLInventoryPanel::DEFAULT_SORT_ORDER, LLSD().with("id", cat_id), panel->getRect(), model, true);
mPanel->postBuild();
mPanel->setFollows(FOLLOWS_ALL);
mPanel->setEnabled(true);
diff --git a/indra/newview/lfsimfeaturehandler.cpp b/indra/newview/lfsimfeaturehandler.cpp
index 65d1e6e55..dbdf2e5de 100644
--- a/indra/newview/lfsimfeaturehandler.cpp
+++ b/indra/newview/lfsimfeaturehandler.cpp
@@ -92,6 +92,7 @@ void LFSimFeatureHandler::setSupportedFeatures()
mGridName = gHippoGridManager->getConnectedGrid()->getGridName() != grid_name ? grid_name : LLStringUtil::null;
}
}
+ has_feature_or_default(mEventsURL, extras, "EventsURL");
has_feature_or_default(mSayRange, extras, "say-range");
has_feature_or_default(mShoutRange, extras, "shout-range");
has_feature_or_default(mWhisperRange, extras, "whisper-range");
@@ -105,6 +106,7 @@ void LFSimFeatureHandler::setSupportedFeatures()
mMapServerURL = LLStringUtil::null;
mSearchURL.reset();
mGridName.reset();
+ mEventsURL.reset();
}
mSayRange.reset();
mShoutRange.reset();
diff --git a/indra/newview/lfsimfeaturehandler.h b/indra/newview/lfsimfeaturehandler.h
index 893edb5a0..9b7554e32 100644
--- a/indra/newview/lfsimfeaturehandler.h
+++ b/indra/newview/lfsimfeaturehandler.h
@@ -65,6 +65,7 @@ public:
boost::signals2::connection setSupportsExportCallback(const SignaledType::slot_t& slot) { return mSupportsExport.connect(slot); }
boost::signals2::connection setDestinationGuideURLCallback(const SignaledType::slot_t& slot) { return mDestinationGuideURL.connect(slot); }
boost::signals2::connection setSearchURLCallback(const SignaledType::slot_t& slot) { return mSearchURL.connect(slot); }
+ boost::signals2::connection setEventsURLCallback(const SignaledType::slot_t& slot) { return mEventsURL.connect(slot); }
boost::signals2::connection setSayRangeCallback(const SignaledType::slot_t& slot) { return mSayRange.connect(slot); }
boost::signals2::connection setShoutRangeCallback(const SignaledType::slot_t& slot) { return mShoutRange.connect(slot); }
boost::signals2::connection setWhisperRangeCallback(const SignaledType::slot_t& slot) { return mWhisperRange.connect(slot); }
@@ -74,6 +75,7 @@ public:
std::string destinationGuideURL() const { return mDestinationGuideURL; }
std::string mapServerURL() const { return mMapServerURL; }
std::string searchURL() const { return mSearchURL; }
+ const std::string& getEventsURL() const { return mEventsURL.ref(); }
const std::string& gridName() const { return mGridName.ref(); }
U32 sayRange() const { return mSayRange; }
U32 shoutRange() const { return mShoutRange; }
@@ -87,6 +89,7 @@ private:
std::string mMapServerURL;
SignaledType mSearchURL;
SignaledType mGridName;
+ SignaledType mEventsURL;
SignaledType mSayRange;
SignaledType mShoutRange;
SignaledType mWhisperRange;
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index c447a4925..457de28d5 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -103,6 +103,7 @@
#include "lluictrlfactory.h" //For LLUICtrlFactory::getLayeredXMLNode
+#include "floaterao.h" // for Typing override
#include "hippolimits.h" // for getMaxAgentGroups
// [RLVa:KB] - Checked: 2011-11-04 (RLVa-1.4.4a)
#include "rlvactions.h"
@@ -2014,10 +2015,7 @@ void LLAgent::startTyping()
}
}
- if (gSavedSettings.getBOOL("PlayTypingAnim"))
- {
- sendAnimationRequest(ANIM_AGENT_TYPE, ANIM_REQUEST_START);
- }
+ LLFloaterAO::typing(true); // Singu Note: Typing anims handled by AO/settings.
gChatBar->
sendChatFromViewer("", CHAT_TYPE_START, FALSE);
}
@@ -2030,7 +2028,7 @@ void LLAgent::stopTyping()
if (mRenderState & AGENT_STATE_TYPING)
{
clearRenderState(AGENT_STATE_TYPING);
- sendAnimationRequest(ANIM_AGENT_TYPE, ANIM_REQUEST_STOP);
+ LLFloaterAO::typing(false); // Singu Note: Typing anims handled by AO/settings.
gChatBar->
sendChatFromViewer("", CHAT_TYPE_STOP, FALSE);
}
@@ -4123,6 +4121,12 @@ void LLAgent::handleTeleportFinished()
LLNotificationsUtil::add("PreferredMaturityChanged", args);
mIsMaturityRatingChangingDuringTeleport = false;
}
+
+ // Init SLM Marketplace connection so we know which UI should be used for the user as a merchant
+ // Note: Eventually, all merchant will be migrated to the new SLM system and there will be no reason to show the old UI at all.
+ // Note: Some regions will not support the SLM cap for a while so we need to do that check for each teleport.
+ // *TODO : Suppress that line from here once the whole grid migrated to SLM and move it to idle_startup() (llstartup.cpp)
+ check_merchant_status();
}
void LLAgent::handleTeleportFailed()
diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp
index e76bd28c3..bb3317005 100644
--- a/indra/newview/llagentcamera.cpp
+++ b/indra/newview/llagentcamera.cpp
@@ -2270,7 +2270,7 @@ void LLAgentCamera::changeCameraToMouselook(BOOL animate)
mMouselookTimer.reset();
gFocusMgr.setKeyboardFocus(NULL);
- if (gSavedSettings.getBOOL("AONoStandsInMouselook")) LLFloaterAO::stopMotion(LLFloaterAO::getCurrentStandId(), FALSE,TRUE);
+ if (gSavedSettings.getBOOL("AONoStandsInMouselook")) LLFloaterAO::stopMotion(LLFloaterAO::getCurrentStandId(), true);
updateLastCamera();
mCameraMode = CAMERA_MODE_MOUSELOOK;
diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp
index 446626b5e..bf5d47d0a 100644
--- a/indra/newview/llagentwearables.cpp
+++ b/indra/newview/llagentwearables.cpp
@@ -32,6 +32,7 @@
#include "llagentcamera.h"
#include "llagentwearablesfetch.h"
#include "llappearancemgr.h"
+#include "llattachmentsmgr.h"
#include "llcallbacklist.h"
#include "llfloatercustomize.h"
#include "llfolderview.h"
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index 7f55b00c9..baa6809ea 100644
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -1568,9 +1568,11 @@ void LLAppearanceMgr::wearItemsOnAvatar(const uuid_vec_t& item_ids_to_wear,
break;
case LLAssetType::AT_OBJECT:
- {
- rez_attachment(item_to_wear, NULL, replace);
- }
+ {
+ LL_DEBUGS("Avatar") << "ATT wearing object. calling rez_attachment, item " << item_to_wear->getName()
+ << " id " << item_to_wear->getLinkedUUID() << LL_ENDL;
+ rez_attachment(item_to_wear, NULL, replace);
+ }
break;
default: continue;
@@ -3759,7 +3761,7 @@ void RequestAgentUpdateAppearanceResponder::onRequestRequested()
}
// Actually send the request.
- LL_DEBUGS("Avatar") << "Will send request for cof_version " << cof_version << LL_ENDL;
+ LL_DEBUGS("Avatar") << "ATT sending bake request for cof_version " << cof_version << LL_ENDL;
mRetryPolicy->reset();
sendRequest();
}
diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h
index 2aee3a578..a0c7fc3d8 100644
--- a/indra/newview/llappearancemgr.h
+++ b/indra/newview/llappearancemgr.h
@@ -321,6 +321,7 @@ private:
nullary_func_t mPostUpdateFunc;
};
+// [SL:KB] - Patch: Appearance-SyncAttach | Checked: 2010-08-31 (Catznip-2.1)
class LLUpdateAppearanceAndEditWearableOnDestroy: public LLInventoryCallback
{
public:
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 1950f5194..a10b6a6e3 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -165,6 +165,7 @@
// in save_settings_to_globals()
#include "llbutton.h"
#include "llcombobox.h"
+#include "floaterlocalassetbrowse.h"
#include "llstatusbar.h"
#include "llsurface.h"
#include "llvosky.h"
@@ -773,7 +774,6 @@ bool LLAppViewer::init()
writeSystemInfo();
-
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
@@ -818,7 +818,14 @@ bool LLAppViewer::init()
LLUrlAction::setOpenURLInternalCallback(boost::bind(&LLWeb::loadURLInternal, _1, LLStringUtil::null, LLStringUtil::null));
LLUrlAction::setOpenURLExternalCallback(boost::bind(&LLWeb::loadURLExternal, _1, true, LLStringUtil::null));
LLUrlAction::setExecuteSLURLCallback(&LLURLDispatcher::dispatchFromTextEditor);
-
+
+ LL_INFOS("InitInfo") << "UI initialization is done." << LL_ENDL ;
+
+ // Load translations for tooltips
+ LLFloater::initClass();
+
+ /////////////////////////////////////////////////
+
LLToolMgr::getInstance(); // Initialize tool manager if not already instantiated
/////////////////////////////////////////////////
@@ -884,7 +891,7 @@ bool LLAppViewer::init()
std::ostringstream msg;
msg << LLTrans::getString("MBUnableToAccessFile");
OSMessageBox(msg.str(),LLStringUtil::null,OSMB_OK);
- return 1;
+ return true;
}
LL_INFOS("InitInfo") << "Cache initialization is done." << LL_ENDL ;
@@ -913,7 +920,7 @@ bool LLAppViewer::init()
load_default_bindings(gSavedSettings.getBOOL("LiruUseZQSDKeys"));
// If we don't have the right GL requirements, exit.
- if (!gGLManager.mHasRequirements && !gNoRender)
+ if (!gGLManager.mHasRequirements)
{
// can't use an alert here since we're exiting and
// all hell breaks lose.
@@ -923,10 +930,9 @@ bool LLAppViewer::init()
msg,
LLStringUtil::null,
OSMB_OK);
- return 0;
+ return false;
}
-#if (_M_IX86_FP > 1 || defined(__SSE2__))
// Without SSE2 support we will crash almost immediately, warn here.
if (!gSysCPU.hasSSE2())
{
@@ -938,23 +944,8 @@ bool LLAppViewer::init()
msg,
LLStringUtil::null,
OSMB_OK);
- return 0;
+ return false;
}
-#elif (_M_IX86_FP == 1 || defined(__SSE__))
- // Without SSE support we will crash almost immediately, warn here.
- if (!gSysCPU.hasSSE())
- {
- // can't use an alert here since we're exiting and
- // all hell breaks lose.
- std::string msg = LNotificationTemplates::instance().getGlobalString("UnsupportedCPUSSE2");
- LLStringUtil::format(msg,LLTrans::getDefaultArgs());
- OSMessageBox(
- msg,
- LLStringUtil::null,
- OSMB_OK);
- return 0;
- }
-#endif
// alert the user if they are using unsupported hardware
if(!gSavedSettings.getBOOL("AlertedUnsupportedHardware"))
@@ -1172,18 +1163,18 @@ bool LLAppViewer::mainLoop()
BOOL restore_rendering_masks = FALSE;
// Handle messages
- while (!LLApp::isExiting())
+ try
{
- LLFastTimer::nextFrame(); // Should be outside of any timer instances
-
- //clear call stack records
- LL_CLEAR_CALLSTACKS();
-
- //check memory availability information
- checkMemory() ;
-
- try
+ while (!LLApp::isExiting())
{
+ LLFastTimer::nextFrame(); // Should be outside of any timer instances
+
+ //clear call stack records
+ LL_CLEAR_CALLSTACKS();
+
+ //check memory availability information
+ checkMemory() ;
+
// Check if we need to restore rendering masks.
if (restore_rendering_masks)
{
@@ -1236,12 +1227,10 @@ bool LLAppViewer::mainLoop()
#endif
//memory leaking simulation
- LLFloaterMemLeak* mem_leak_instance =
- LLFloaterMemLeak::getInstance();
- if(mem_leak_instance)
+ if (auto mem_leak_instance = LLFloaterMemLeak::getInstance())
{
- mem_leak_instance->idle() ;
- }
+ mem_leak_instance->idle();
+ }
// canonical per-frame event
mainloop.post(newFrame);
@@ -1424,54 +1413,29 @@ bool LLAppViewer::mainLoop()
// LLAppViewer::getTextureFetch()->pause(); // Don't pause the fetch (IO) thread
}
//LLVFSThread::sLocal->pause(); // Prevent the VFS thread from running while rendering.
- //LLLFSThread::sLocal->pause(); // Prevent the LFS thread from running while rendering.
resumeMainloopTimeout();
pingMainloopTimeout("Main:End");
}
}
- catch(std::bad_alloc)
- {
- LLMemory::logMemoryInfo(TRUE) ;
- //stop memory leaking simulation
- LLFloaterMemLeak* mem_leak_instance =
- LLFloaterMemLeak::getInstance();
- if(mem_leak_instance)
- {
- mem_leak_instance->stop() ;
- LL_WARNS() << "Bad memory allocation in LLAppViewer::mainLoop()!" << LL_ENDL ;
- }
- else
- {
- //output possible call stacks to log file.
- LLError::LLCallStacks::print() ;
-
- LL_ERRS() << "Bad memory allocation in LLAppViewer::mainLoop()!" << LL_ENDL ;
- }
- }
- }
-
- // Save snapshot for next time, if we made it through initialization
- if (STATE_STARTED == LLStartUp::getStartupState())
- {
- try
- {
+ // Save snapshot for next time, if we made it through initialization
+ if (STATE_STARTED == LLStartUp::getStartupState())
saveFinalSnapshot();
- }
- catch(std::bad_alloc)
- {
- LL_WARNS() << "Bad memory allocation when saveFinalSnapshot() is called!" << LL_ENDL ;
+ }
+ catch(std::bad_alloc)
+ {
+ LLMemory::logMemoryInfo(TRUE);
- //stop memory leaking simulation
- LLFloaterMemLeak* mem_leak_instance =
- LLFloaterMemLeak::getInstance();
- if(mem_leak_instance)
- {
- mem_leak_instance->stop() ;
- }
- }
+ //stop memory leaking simulation
+ if (auto mem_leak_instance = LLFloaterMemLeak::getInstance())
+ mem_leak_instance->stop();
+
+ //output possible call stacks to log file.
+ LLError::LLCallStacks::print();
+
+ LL_ERRS() << "Bad memory allocation in LLAppViewer::mainLoop()!" << LL_ENDL;
}
delete gServicePump;
@@ -1733,6 +1697,8 @@ bool LLAppViewer::cleanup()
LLFloaterTeleportHistory::saveFile("teleport_history.xml");
+ LocalAssetBrowser::deleteSingleton(); //
+
// save mute list. gMuteList used to also be deleted here too.
LLMuteList::getInstance()->cache(gAgent.getID());
@@ -2474,12 +2440,11 @@ bool LLAppViewer::initConfiguration()
//
// Set the name of the window
//
- gWindowTitle = LLTrans::getString("APP_NAME");
+ gWindowTitle = LLTrans::getString("APP_NAME") + llformat(" (%d) ", LLVersionInfo::getBuild())
#if LL_DEBUG
- gWindowTitle += std::string(" [DEBUG] ") + gArgs;
-#else
- gWindowTitle += std::string(" ") + gArgs;
+ + "[DEBUG] "
#endif
+ + gArgs;
LLStringUtil::truncate(gWindowTitle, 255);
//RN: if we received a URL, hand it off to the existing instance.
@@ -2679,6 +2644,8 @@ void LLAppViewer::cleanupSavedSettings()
{
gSavedSettings.setF32("RenderFarClip", gAgentCamera.mDrawDistance);
}
+
+ LLSpeakerVolumeStorage::deleteSingleton();
}
void LLAppViewer::removeCacheFiles(const std::string& file_mask)
diff --git a/indra/newview/llattachmentsmgr.cpp b/indra/newview/llattachmentsmgr.cpp
index 21ca02e38..e556ec61b 100644
--- a/indra/newview/llattachmentsmgr.cpp
+++ b/indra/newview/llattachmentsmgr.cpp
@@ -39,6 +39,7 @@
#include "rlvhandler.h"
#include "rlvlocks.h"
// [/RLVa:KB]
+#include
const F32 COF_LINK_BATCH_TIME = 5.0F;
const F32 MAX_ATTACHMENT_REQUEST_LIFETIME = 30.0F;
@@ -478,9 +479,17 @@ void LLAttachmentsMgr::onAttachmentArrived(const LLUUID& inv_item_id)
{
LLTimer timer;
bool expected = mAttachmentRequests.getTime(inv_item_id, timer);
+ LLInventoryItem *item = gInventory.getItem(inv_item_id);
+
+ if (item && boost::algorithm::contains(item->getName(), " Bridge v") && gSavedSettings.getBOOL("SGDetachBridge"))
+ {
+ LL_INFOS() << "Bridge detected! detaching" << LL_ENDL;
+ LLVOAvatarSelf::detachAttachmentIntoInventory(item->getUUID());
+ return;
+ }
+
if (!expected)
{
- LLInventoryItem *item = gInventory.getItem(inv_item_id);
LL_WARNS() << "ATT Attachment was unexpected or arrived after " << MAX_ATTACHMENT_REQUEST_LIFETIME << " seconds: "
<< (item ? item->getName() : "UNKNOWN") << " id " << inv_item_id << LL_ENDL;
}
diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index 9609d60ff..269c24956 100644
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -546,20 +546,12 @@ void LLAvatarActions::csr(const LLUUID& id)
if (!gCacheName->getFullName(id, name)) return;
std::string url = "http://csr.lindenlab.com/agent/";
-
- // slow and stupid, but it's late
- S32 len = name.length();
- for (S32 i = 0; i < len; i++)
+ if (char* output = curl_easy_escape(nullptr, name.c_str(), name.length()))
{
- if (name[i] == ' ')
- {
- url += "%20";
- }
- else
- {
- url += name[i];
- }
+ name = output;
+ curl_free(output);
}
+ url += name;
LLWeb::loadURL(url);
}
diff --git a/indra/newview/llcontrolavatar.cpp b/indra/newview/llcontrolavatar.cpp
index f11e228ba..75ab16c18 100644
--- a/indra/newview/llcontrolavatar.cpp
+++ b/indra/newview/llcontrolavatar.cpp
@@ -113,7 +113,7 @@ void LLControlAvatar::getNewConstraintFixups(LLVector3& new_pos_fixup, F32& new_
unshift_extents[0] = extents[0] - mPositionConstraintFixup;
unshift_extents[1] = extents[1] - mPositionConstraintFixup;
LLVector3 box_dims = extents[1]-extents[0];
- F32 box_size = llmax(box_dims[0],box_dims[1],box_dims[2]);
+ //F32 box_size = llmax(box_dims[0],box_dims[1],box_dims[2]);
if (!mRootVolp->isAttachment())
{
diff --git a/indra/newview/llcurrencyuimanager.cpp b/indra/newview/llcurrencyuimanager.cpp
index 7609358b5..3320e609b 100644
--- a/indra/newview/llcurrencyuimanager.cpp
+++ b/indra/newview/llcurrencyuimanager.cpp
@@ -387,6 +387,7 @@ void LLCurrencyUIManager::Impl::updateUI()
}
mPanel.childSetTextArg("currency_est", "[USD]", llformat("%#.2f", mSiteCurrencyEstimatedCost / 100.0));
+ mPanel.childSetTextArg("currency_est", "[REALCURRENCY]", gHippoGridManager->getConnectedGrid()->getRealCurrencySymbol());
mPanel.childSetVisible("currency_est", mSiteCurrencyEstimated && mUserCurrencyBuy > 0);
if (mPanel.childIsEnabled("buy_btn")
diff --git a/indra/newview/lldebugmessagebox.cpp b/indra/newview/lldebugmessagebox.cpp
index d485c7a9d..7073d9b05 100644
--- a/indra/newview/lldebugmessagebox.cpp
+++ b/indra/newview/lldebugmessagebox.cpp
@@ -56,25 +56,25 @@ LLDebugVarMessageBox::LLDebugVarMessageBox(const std::string& title, EDebugVarTy
switch(var_type)
{
case VAR_TYPE_F32:
- mSlider1 = new LLSliderCtrl(std::string("slider 1"), LLRect(20,130,190,110), title, NULL, 70, 130, TRUE, TRUE, FALSE, NULL, *((F32*)var), -100.f, 100.f, 0.1f, LLStringUtil::null);
+ mSlider1 = new LLSliderCtrl(std::string("slider 1"), LLRect(20,130,190,110), title, NULL, 70, 130, TRUE, TRUE, NULL, *((F32*)var), -100.f, 100.f, 0.1f, LLStringUtil::null);
mSlider1->setPrecision(3);
addChild(mSlider1);
mSlider2 = NULL;
mSlider3 = NULL;
break;
case VAR_TYPE_S32:
- mSlider1 = new LLSliderCtrl(std::string("slider 1"), LLRect(20,100,190,80), title, NULL, 70, 130, TRUE, TRUE, FALSE, NULL, (F32)*((S32*)var), -255.f, 255.f, 1.f, LLStringUtil::null);
+ mSlider1 = new LLSliderCtrl(std::string("slider 1"), LLRect(20,100,190,80), title, NULL, 70, 130, TRUE, TRUE, NULL, (F32)*((S32*)var), -255.f, 255.f, 1.f, LLStringUtil::null);
mSlider1->setPrecision(0);
addChild(mSlider1);
mSlider2 = NULL;
mSlider3 = NULL;
break;
case VAR_TYPE_VEC3:
- mSlider1 = new LLSliderCtrl(std::string("slider 1"), LLRect(20,130,190,110), std::string("x: "), NULL, 70, 130, TRUE, TRUE, FALSE, NULL, ((LLVector3*)var)->mV[VX], -100.f, 100.f, 0.1f, LLStringUtil::null);
+ mSlider1 = new LLSliderCtrl(std::string("slider 1"), LLRect(20,130,190,110), std::string("x: "), NULL, 70, 130, TRUE, TRUE, NULL, ((LLVector3*)var)->mV[VX], -100.f, 100.f, 0.1f, LLStringUtil::null);
mSlider1->setPrecision(3);
- mSlider2 = new LLSliderCtrl(std::string("slider 2"), LLRect(20,100,190,80), std::string("y: "), NULL, 70, 130, TRUE, TRUE, FALSE, NULL, ((LLVector3*)var)->mV[VY], -100.f, 100.f, 0.1f, LLStringUtil::null);
+ mSlider2 = new LLSliderCtrl(std::string("slider 2"), LLRect(20,100,190,80), std::string("y: "), NULL, 70, 130, TRUE, TRUE, NULL, ((LLVector3*)var)->mV[VY], -100.f, 100.f, 0.1f, LLStringUtil::null);
mSlider2->setPrecision(3);
- mSlider3 = new LLSliderCtrl(std::string("slider 3"), LLRect(20,70,190,50), std::string("z: "), NULL, 70, 130, TRUE, TRUE, FALSE, NULL, ((LLVector3*)var)->mV[VZ], -100.f, 100.f, 0.1f, LLStringUtil::null);
+ mSlider3 = new LLSliderCtrl(std::string("slider 3"), LLRect(20,70,190,50), std::string("z: "), NULL, 70, 130, TRUE, TRUE, NULL, ((LLVector3*)var)->mV[VZ], -100.f, 100.f, 0.1f, LLStringUtil::null);
mSlider3->setPrecision(3);
addChild(mSlider1);
addChild(mSlider2);
diff --git a/indra/newview/llenvmanager.cpp b/indra/newview/llenvmanager.cpp
index 4abd7fc8e..d2fb204cc 100644
--- a/indra/newview/llenvmanager.cpp
+++ b/indra/newview/llenvmanager.cpp
@@ -505,7 +505,7 @@ void LLEnvManagerNew::onRegionSettingsResponse(const LLSD& content)
mRegionSettingsChangeSignal();
// reset
- if (!gHippoGridManager->getConnectedGrid()->isAurora()) // On Aurora, the region says when to refresh
+ if (!gHippoGridManager->getConnectedGrid()->isWhiteCore()) // On WhiteCore, the region says when to refresh
mInterpNextChangeMessage = false;
}
@@ -704,7 +704,7 @@ void LLEnvManagerNew::onRegionChange()
}
}
-// Aurora-sim windlight refresh
+// WhiteCore windlight refresh
class WindLightRefresh : public LLHTTPNode
{
/*virtual*/ void post(LLHTTPNode::ResponsePtr response, const LLSD& context, const LLSD& input) const
diff --git a/indra/newview/lleventpoll.cpp b/indra/newview/lleventpoll.cpp
index 22b715590..b804b81be 100644
--- a/indra/newview/lleventpoll.cpp
+++ b/indra/newview/lleventpoll.cpp
@@ -190,6 +190,20 @@ namespace
mErrorCount = 0;
makeRequest();
}
+ else if (mStatus == HTTP_NOT_FOUND)
+ { // Event polling for this server has been canceled. In
+ // some cases the server gets ahead of the viewer and will
+ // return a 404 error (Not Found) before the cancel event
+ // comes back in the queue
+ LL_WARNS("LLEventPollImpl") << "Canceling coroutine" << LL_ENDL;
+ stop();
+ }
+ else if (mCode != CURLE_OK)
+ {
+ /// Some LLCore or LIBCurl error was returned. This is unlikely to be recoverable
+ LL_WARNS("LLEventPollImpl") << "Critical error from poll request returned from libraries. Canceling coroutine." << LL_ENDL;
+ stop();
+ }
else if (mErrorCount < MAX_EVENT_POLL_HTTP_ERRORS)
{
++mErrorCount;
@@ -213,6 +227,7 @@ namespace
// They are essentially disconnected from the region even though some things may still work.
// Since things won't get better until they relog we force a disconnect now.
+ /* Singu Note: There's no reason to disconnect, just because this failed a few too many times
// *NOTE:Mani - The following condition check to see if this failing event poll
// is attached to the Agent's main region. If so we disconnect the viewer.
// Else... its a child region and we just leave the dead event poll stopped and
@@ -222,6 +237,7 @@ namespace
LL_WARNS() << "Forcing disconnect due to stalled main region event poll." << LL_ENDL;
LLAppViewer::instance()->forceDisconnect(LLTrans::getString("AgentLostConnection"));
}
+ */
}
}
diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp
new file mode 100644
index 000000000..d578b6062
--- /dev/null
+++ b/indra/newview/llfavoritesbar.cpp
@@ -0,0 +1,1802 @@
+// This is an open source non-commercial project. Dear PVS-Studio, please check it.
+// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
+/**
+ * @file llfavoritesbar.cpp
+ * @brief LLFavoritesBarCtrl class implementation
+ *
+ * $LicenseInfo:firstyear=2009&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+#include "llfavoritesbar.h"
+
+//#include "llfloaterreg.h"
+#include "llfocusmgr.h"
+#include "llinventory.h"
+#include "lllandmarkactions.h"
+//#include "lltoolbarview.h"
+#include "lltrans.h"
+#include "llmenugl.h"
+//#include "lltooltip.h"
+#include "lluictrlfactory.h"
+
+#include "llagent.h"
+#include "llavatarnamecache.h"
+#include "llclipboard.h"
+#include "llinventorybridge.h"
+#include "llinventoryclipboard.h"
+#include "llinventoryfunctions.h"
+//#include "llfloatersidepanelcontainer.h"
+#include "llfloaterworldmap.h"
+#include "lllandmarkactions.h"
+//#include "lllogininstance.h"
+#include "llnotificationsutil.h"
+//#include "lltoggleablemenu.h"
+#include "llviewerinventory.h"
+#include "llviewermenu.h"
+#include "hippogridmanager.h" //"llviewernetwork.h"
+#include "lltooldraganddrop.h"
+#include "llsdserialize.h"
+
+void open_landmark(LLViewerInventoryItem* inv_item, const std::string& title, BOOL show_keep_discard, const LLUUID& source_id, BOOL take_focus);
+
+static LLRegisterWidget r("favorites_bar");
+
+const S32 DROP_DOWN_MENU_WIDTH = 250;
+const S32 DROP_DOWN_MENU_TOP_PAD = 13;
+
+/**
+ * Helper for LLFavoriteLandmarkButton and LLFavoriteLandmarkMenuItem.
+ * Performing requests for SLURL for given Landmark ID
+ */
+class LLLandmarkInfoGetter
+{
+public:
+ LLLandmarkInfoGetter()
+ : mLandmarkID(LLUUID::null),
+ mName("(Loading...)"),
+ mPosX(0),
+ mPosY(0),
+ mPosZ(0),
+ mLoaded(false)
+ {
+ mHandle.bind(this);
+ }
+
+ void setLandmarkID(const LLUUID& id) { mLandmarkID = id; }
+ const LLUUID& getLandmarkId() const { return mLandmarkID; }
+
+ const std::string& getName()
+ {
+ if(!mLoaded)
+ requestNameAndPos();
+
+ return mName;
+ }
+
+ S32 getPosX()
+ {
+ if (!mLoaded)
+ requestNameAndPos();
+ return mPosX;
+ }
+
+ S32 getPosY()
+ {
+ if (!mLoaded)
+ requestNameAndPos();
+ return mPosY;
+ }
+
+ S32 getPosZ()
+ {
+ if (!mLoaded)
+ requestNameAndPos();
+ return mPosZ;
+ }
+
+private:
+ /**
+ * Requests landmark data from server.
+ */
+ void requestNameAndPos()
+ {
+ if (mLandmarkID.isNull())
+ return;
+
+ LLVector3d g_pos;
+ if(LLLandmarkActions::getLandmarkGlobalPos(mLandmarkID, g_pos))
+ {
+ LLLandmarkActions::getRegionNameAndCoordsFromPosGlobal(g_pos,
+ boost::bind(&LLLandmarkInfoGetter::landmarkNameCallback, static_cast >(mHandle), _1, _2, _3, _4));
+ }
+ }
+
+ static void landmarkNameCallback(LLHandle handle, const std::string& name, S32 x, S32 y, S32 z)
+ {
+ LLLandmarkInfoGetter* getter = handle.get();
+ if (getter)
+ {
+ getter->mPosX = x;
+ getter->mPosY = y;
+ getter->mPosZ = z;
+ getter->mName = name;
+ getter->mLoaded = true;
+ }
+ }
+
+ LLUUID mLandmarkID;
+ std::string mName;
+ S32 mPosX;
+ S32 mPosY;
+ S32 mPosZ;
+ bool mLoaded;
+ LLRootHandle mHandle;
+};
+
+/**
+ * This class is needed to override LLButton default handleToolTip function and
+ * show SLURL as button tooltip.
+ * *NOTE: dzaporozhan: This is a workaround. We could set tooltips for buttons
+ * in createButtons function but landmark data is not available when Favorites Bar is
+ * created. Thats why we are requesting landmark data after
+ */
+class LLFavoriteLandmarkButton : public LLButton
+{
+public:
+
+ BOOL handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect) override
+ {
+ std::string region_name = mLandmarkInfoGetter.getName();
+
+ if (!region_name.empty())
+ {
+ std::string extra_message = llformat("%s (%d, %d, %d)", region_name.c_str(),
+ mLandmarkInfoGetter.getPosX(), mLandmarkInfoGetter.getPosY(), mLandmarkInfoGetter.getPosZ());
+
+ msg = llformat("%s\n%s", getLabelSelected().c_str(), extra_message.c_str());
+ *sticky_rect = calcScreenRect();
+ }
+ return TRUE;
+ }
+
+ /*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask) override
+ {
+ LLFavoritesBarCtrl* fb = dynamic_cast(getParent());
+
+ if (fb)
+ {
+ fb->handleHover(x, y, mask);
+ }
+
+ return LLButton::handleHover(x, y, mask);
+ }
+
+ void setLandmarkID(const LLUUID& id){ mLandmarkInfoGetter.setLandmarkID(id); }
+ const LLUUID& getLandmarkId() const { return mLandmarkInfoGetter.getLandmarkId(); }
+
+ void onMouseEnter(S32 x, S32 y, MASK mask) override
+ {
+ if (LLToolDragAndDrop::getInstance()->hasMouseCapture())
+ {
+ LLUICtrl::onMouseEnter(x, y, mask);
+ }
+ else
+ {
+ LLButton::onMouseEnter(x, y, mask);
+ }
+ }
+
+//protected:
+ LLFavoriteLandmarkButton(const LLButton::Params& p) : LLButton(p) {}
+ friend class LLUICtrlFactory;
+
+private:
+ LLLandmarkInfoGetter mLandmarkInfoGetter;
+};
+
+/**
+ * This class is needed to override LLMenuItemCallGL default handleToolTip function and
+ * show SLURL as button tooltip.
+ * *NOTE: dzaporozhan: This is a workaround. We could set tooltips for buttons
+ * in showDropDownMenu function but landmark data is not available when Favorites Bar is
+ * created. Thats why we are requesting landmark data after
+ */
+class LLFavoriteLandmarkMenuItem : public LLMenuItemCallGL
+{
+public:
+ BOOL handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect) override
+ {
+ std::string region_name = mLandmarkInfoGetter.getName();
+ if (!region_name.empty())
+ {
+ msg = llformat("%s\n%s (%d, %d)", getLabel().c_str(), region_name.c_str(), mLandmarkInfoGetter.getPosX(), mLandmarkInfoGetter.getPosY());
+ *sticky_rect = calcScreenRect();
+ }
+ return TRUE;
+ }
+
+ void setLandmarkID(const LLUUID& id){ mLandmarkInfoGetter.setLandmarkID(id); }
+
+ BOOL handleMouseDown(S32 x, S32 y, MASK mask) override
+ {
+ if (mMouseDownSignal)
+ (*mMouseDownSignal)(this, x, y, mask);
+ return LLMenuItemCallGL::handleMouseDown(x, y, mask);
+ }
+
+ BOOL handleMouseUp(S32 x, S32 y, MASK mask) override
+ {
+ if (mMouseUpSignal)
+ (*mMouseUpSignal)(this, x, y, mask);
+ return LLMenuItemCallGL::handleMouseUp(x, y, mask);
+ }
+
+ BOOL handleHover(S32 x, S32 y, MASK mask) override
+ {
+ if (fb)
+ {
+ fb->handleHover(x, y, mask);
+ }
+
+ return TRUE;
+ }
+
+ void initFavoritesBarPointer(LLFavoritesBarCtrl* fb) { this->fb = fb; }
+
+//protected:
+
+ LLFavoriteLandmarkMenuItem(const LLMenuItemCallGL::Params& p) : LLMenuItemCallGL(p.name(), p.label(), nullptr), fb(nullptr) {}
+ friend class LLUICtrlFactory;
+
+private:
+ LLLandmarkInfoGetter mLandmarkInfoGetter;
+ LLFavoritesBarCtrl* fb;
+};
+
+/**
+ * This class was introduced just for fixing the following issue:
+ * EXT-836 Nav bar: Favorites overflow menu passes left-mouse click through.
+ * We must explicitly handle drag and drop event by returning TRUE
+ * because otherwise LLToolDragAndDrop will initiate drag and drop operation
+ * with the world.
+ */
+class LLFavoriteLandmarkToggleableMenu : public LLMenuGL
+{
+public:
+ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
+ EDragAndDropType cargo_type,
+ void* cargo_data,
+ EAcceptance* accept,
+ std::string& tooltip_msg) override
+ {
+ *accept = ACCEPT_NO;
+ return TRUE;
+ }
+
+//protected:
+ LLFavoriteLandmarkToggleableMenu():
+ LLMenuGL("favorites menu")
+ {
+ }
+
+ friend class LLUICtrlFactory;
+};
+
+/**
+ * This class is needed to update an item being copied to the favorites folder
+ * with a sort field value (required to save favorites bar's tabs order).
+ * See method handleNewFavoriteDragAndDrop for more details on how this class is used.
+ */
+class LLItemCopiedCallback : public LLInventoryCallback
+{
+public:
+ LLItemCopiedCallback(S32 sortField): mSortField(sortField) {}
+
+ void fire(const LLUUID& inv_item) override
+ {
+ LLViewerInventoryItem* item = gInventory.getItem(inv_item);
+
+ if (item)
+ {
+ LLFavoritesOrderStorage::instance().setSortIndex(item, mSortField);
+
+ item->setComplete(TRUE);
+ item->updateServer(FALSE);
+
+ gInventory.updateItem(item);
+ gInventory.notifyObservers();
+ LLFavoritesOrderStorage::instance().saveOrder();
+ }
+
+ LLView::getWindow()->setCursor(UI_CURSOR_ARROW);
+ }
+
+private:
+ S32 mSortField;
+};
+
+// updateButtons's helper
+struct LLFavoritesSort
+{
+ // Sorting by creation date and name
+ // TODO - made it customizible using gSavedSettings
+ bool operator()(const LLViewerInventoryItem* const& a, const LLViewerInventoryItem* const& b) const
+ {
+ S32 sortField1 = LLFavoritesOrderStorage::instance().getSortIndex(a->getUUID());
+ S32 sortField2 = LLFavoritesOrderStorage::instance().getSortIndex(b->getUUID());
+
+ if (!(sortField1 < 0 && sortField2 < 0))
+ {
+ return sortField2 > sortField1;
+ }
+
+ time_t first_create = a->getCreationDate();
+ time_t second_create = b->getCreationDate();
+ if (first_create == second_create)
+ {
+ return (LLStringUtil::compareDict(a->getName(), b->getName()) < 0);
+ }
+ else
+ {
+ return (first_create > second_create);
+ }
+ }
+};
+
+LLFavoritesBarCtrl::Params::Params()
+: image_drag_indication("image_drag_indication"),
+ more_button("more_button"),
+ label("label")
+{
+}
+
+LLFavoritesBarCtrl::LLFavoritesBarCtrl(const LLFavoritesBarCtrl::Params& p)
+: LLUICtrl(p),
+ mOverflowMenuHandle(),
+ mContextMenuHandle(),
+ mFont(p.font.isProvided() ? p.font() : LLFontGL::getFontSansSerifSmall()),
+ mUpdateDropDownItems(true),
+ mRestoreOverflowMenu(false),
+ mImageDragIndication(p.image_drag_indication),
+ mShowDragMarker(FALSE),
+ mLandingTab(NULL)
+ , mLastTab(NULL)
+, mTabsHighlightEnabled(TRUE)
+{
+ // Register callback for menus with current registrar (will be parent panel's registrar)
+ LLUICtrl::CommitCallbackRegistry::currentRegistrar().add("Favorites.DoToSelected",
+ boost::bind(&LLFavoritesBarCtrl::doToSelected, this, _2));
+
+ // Add this if we need to selectively enable items
+ LLUICtrl::EnableCallbackRegistry::currentRegistrar().add("Favorites.EnableSelected",
+ boost::bind(&LLFavoritesBarCtrl::enableSelected, this, _2));
+
+ gInventory.addObserver(this);
+
+ //make chevron button
+ mMoreTextBox = new LLTextBox(">>", "\u0032", 50);
+ mMoreTextBox->setFollows(FOLLOWS_LEFT | FOLLOWS_BOTTOM);
+ mMoreTextBox->setToolTip(LLStringExplicit("Show more of My Favorites"));
+ mMoreTextBox->setTabStop(false);
+ mMoreTextBox->setClickedCallback(boost::bind(&LLFavoritesBarCtrl::showDropDownMenu, this));
+ addChild(mMoreTextBox);
+
+ mDropDownItemsCount = 0;
+
+ mBarLabel = new LLTextBox(p.label.name, p.label.label);
+ addChild(mBarLabel);
+}
+
+LLFavoritesBarCtrl::~LLFavoritesBarCtrl()
+{
+ gInventory.removeObserver(this);
+
+ if (mOverflowMenuHandle.get()) mOverflowMenuHandle.get()->die();
+ if (mContextMenuHandle.get()) mContextMenuHandle.get()->die();
+}
+
+BOOL LLFavoritesBarCtrl::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
+ EDragAndDropType cargo_type,
+ void* cargo_data,
+ EAcceptance* accept,
+ std::string& tooltip_msg)
+{
+ *accept = ACCEPT_NO;
+
+ LLToolDragAndDrop::ESource source = LLToolDragAndDrop::getInstance()->getSource();
+ if (LLToolDragAndDrop::SOURCE_AGENT != source && LLToolDragAndDrop::SOURCE_LIBRARY != source) return FALSE;
+
+ switch (cargo_type)
+ {
+
+ case DAD_LANDMARK:
+ {
+ /*
+ * add a callback to the end drag event.
+ * the callback will disconnet itself immediately after execution
+ * this is done because LLToolDragAndDrop is a common tool so it shouldn't
+ * be overloaded with redundant callbacks.
+ */
+ if (!mEndDragConnection.connected())
+ {
+ mEndDragConnection = LLToolDragAndDrop::getInstance()->setEndDragCallback(boost::bind(&LLFavoritesBarCtrl::onEndDrag, this));
+ }
+
+ // Copy the item into the favorites folder (if it's not already there).
+ LLInventoryItem *item = (LLInventoryItem *)cargo_data;
+
+ if (LLFavoriteLandmarkButton* dest = dynamic_cast(findChildByLocalCoords(x, y)))
+ {
+ setLandingTab(dest);
+ }
+ else if (mLastTab && (x >= mLastTab->getRect().mRight))
+ {
+ /*
+ * the condition dest == NULL can be satisfied not only in the case
+ * of dragging to the right from the last tab of the favbar. there is a
+ * small gap between each tab. if the user drags something exactly there
+ * then mLandingTab will be set to NULL and the dragged item will be pushed
+ * to the end of the favorites bar. this is incorrect behavior. that's why
+ * we need an additional check which excludes the case described previously
+ * making sure that the mouse pointer is beyond the last tab.
+ */
+ setLandingTab(NULL);
+ }
+
+ // check if we are dragging an existing item from the favorites bar
+ if (item && mDragItemId == item->getUUID())
+ {
+ *accept = ACCEPT_YES_SINGLE;
+
+ showDragMarker(TRUE);
+
+ if (drop)
+ {
+ handleExistingFavoriteDragAndDrop(x, y);
+ }
+ }
+ else
+ {
+ const LLUUID favorites_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
+ if (item && item->getParentUUID() == favorites_id)
+ {
+ LL_WARNS("FavoritesBar") << "Attemt to copy a favorite item into the same folder." << LL_ENDL;
+ break;
+ }
+
+ *accept = ACCEPT_YES_COPY_MULTI;
+
+ showDragMarker(TRUE);
+
+ if (drop)
+ {
+ if (mItems.empty())
+ {
+ setLandingTab(NULL);
+ }
+ handleNewFavoriteDragAndDrop(item, favorites_id, x, y);
+ }
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
+ return TRUE;
+}
+
+void LLFavoritesBarCtrl::handleExistingFavoriteDragAndDrop(S32 x, S32 y)
+{
+ // Identify the button hovered and the side to drop
+ LLFavoriteLandmarkButton* dest = dynamic_cast(mLandingTab);
+ bool insert_before = true;
+ if (!dest)
+ {
+ insert_before = false;
+ dest = dynamic_cast(mLastTab);
+ }
+
+ // There is no need to handle if an item was dragged onto itself
+ if (dest && dest->getLandmarkId() == mDragItemId)
+ {
+ return;
+ }
+
+ // Insert the dragged item in the right place
+ if (dest)
+ {
+ LLInventoryModel::updateItemsOrder(mItems, mDragItemId, dest->getLandmarkId(), insert_before);
+ }
+ else
+ {
+ // This can happen when the item list is empty
+ mItems.push_back(gInventory.getItem(mDragItemId));
+ }
+
+ LLFavoritesOrderStorage::instance().saveItemsOrder(mItems);
+
+ LLMenuGL* menu = (LLMenuGL*) mOverflowMenuHandle.get();
+
+ if (menu && menu->getVisible())
+ {
+ menu->setVisible(FALSE);
+ showDropDownMenu();
+ }
+}
+
+void LLFavoritesBarCtrl::handleNewFavoriteDragAndDrop(LLInventoryItem *item, const LLUUID& favorites_id, S32 x, S32 y)
+{
+ if (!item) return;
+ // Identify the button hovered and the side to drop
+ LLFavoriteLandmarkButton* dest = NULL;
+ bool insert_before = true;
+ if (!mItems.empty())
+ {
+ // [MAINT-2386] When multiple landmarks are selected and dragged onto an empty favorites bar,
+ // the viewer would crash when casting mLastTab below, as mLastTab is still null when the
+ // second landmark is being added.
+ // To ensure mLastTab is valid, we need to call updateButtons() at the end of this function
+ dest = dynamic_cast(mLandingTab);
+ if (!dest)
+ {
+ insert_before = false;
+ dest = dynamic_cast(mLastTab);
+ }
+ }
+
+ // There is no need to handle if an item was dragged onto itself
+ if (dest && dest->getLandmarkId() == mDragItemId)
+ {
+ return;
+ }
+
+ LLPointer viewer_item = new LLViewerInventoryItem(item);
+
+ // Insert the dragged item in the right place
+ if (dest)
+ {
+ insertItem(mItems, dest->getLandmarkId(), viewer_item, insert_before);
+ }
+ else
+ {
+ // This can happen when the item list is empty
+ mItems.push_back(viewer_item);
+ }
+
+ int sortField = 0;
+ LLPointer cb;
+
+ // current order is saved by setting incremental values (1, 2, 3, ...) for the sort field
+ for (LLInventoryModel::item_array_t::iterator i = mItems.begin(); i != mItems.end(); ++i)
+ {
+ LLViewerInventoryItem* currItem = *i;
+
+ if (currItem->getUUID() == item->getUUID())
+ {
+ cb = new LLItemCopiedCallback(++sortField);
+ }
+ else
+ {
+ LLFavoritesOrderStorage::instance().setSortIndex(currItem, ++sortField);
+
+ currItem->setComplete(TRUE);
+ currItem->updateServer(FALSE);
+
+ gInventory.updateItem(currItem);
+ }
+ }
+
+ LLToolDragAndDrop* tool_dad = LLToolDragAndDrop::getInstance();
+ if (tool_dad->getSource() == LLToolDragAndDrop::SOURCE_NOTECARD)
+ {
+ viewer_item->setType(LLAssetType::AT_LANDMARK);
+ copy_inventory_from_notecard(favorites_id,
+ tool_dad->getObjectID(),
+ tool_dad->getSourceID(),
+ viewer_item.get(),
+ gInventoryCallbacks.registerCB(cb));
+ }
+ else
+ {
+ copy_inventory_item(
+ gAgent.getID(),
+ item->getPermissions().getOwner(),
+ item->getUUID(),
+ favorites_id,
+ std::string(),
+ cb);
+ }
+
+ // [MAINT-2386] Ensure the favorite button has been created and is valid.
+ // This also ensures that mLastTab will be valid when dropping multiple
+ // landmarks to an empty favorites bar.
+ updateButtons();
+
+ LL_INFOS("FavoritesBar") << "Copied inventory item #" << item->getUUID() << " to favorites." << LL_ENDL;
+}
+
+//virtual
+void LLFavoritesBarCtrl::changed(U32 mask)
+{
+ if (mFavoriteFolderId.isNull())
+ {
+ mFavoriteFolderId = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
+
+ if (mFavoriteFolderId.notNull())
+ {
+ gInventory.fetchDescendentsOf(mFavoriteFolderId);
+ }
+ }
+ else
+ {
+ LLInventoryModel::item_array_t items;
+ LLInventoryModel::cat_array_t cats;
+ LLIsType is_type(LLAssetType::AT_LANDMARK);
+ gInventory.collectDescendentsIf(mFavoriteFolderId, cats, items, LLInventoryModel::EXCLUDE_TRASH, is_type);
+
+ for (LLInventoryModel::item_array_t::iterator i = items.begin(); i != items.end(); ++i)
+ {
+ LLFavoritesOrderStorage::instance().getSLURL((*i)->getAssetUUID());
+ }
+
+ updateButtons();
+ }
+}
+
+//virtual
+void LLFavoritesBarCtrl::reshape(S32 width, S32 height, BOOL called_from_parent)
+{
+ LLUICtrl::reshape(width, height, called_from_parent);
+ updateButtons();
+}
+
+void LLFavoritesBarCtrl::draw()
+{
+ LLUICtrl::draw();
+
+ if (mShowDragMarker)
+ {
+ S32 w = mImageDragIndication->getWidth();
+ S32 h = mImageDragIndication->getHeight();
+
+ if (mLandingTab)
+ {
+ // mouse pointer hovers over an existing tab
+ LLRect rect = mLandingTab->getRect();
+ mImageDragIndication->draw(rect.mLeft, rect.getHeight(), w, h);
+ }
+ else if (mLastTab)
+ {
+ // mouse pointer hovers over the favbar empty space (right to the last tab)
+ LLRect rect = mLastTab->getRect();
+ mImageDragIndication->draw(rect.mRight, rect.getHeight(), w, h);
+ }
+ // Once drawn, mark this false so we won't draw it again (unless we hit the favorite bar again)
+ mShowDragMarker = FALSE;
+ }
+}
+
+const LLButton::Params& LLFavoritesBarCtrl::getButtonParams()
+{
+ static LLButton::Params button_params;
+ static bool params_initialized = false;
+
+ if (!params_initialized)
+ {
+ button_params.image_overlay(LLUI::getUIImage("Favorite_Link_Over"))
+ .hover_glow_amount(0.15f)
+ .use_ellipses(true).tab_stop(false)
+ .name("favorites_bar_btn")
+ .follows.flags(FOLLOWS_LEFT|FOLLOWS_BOTTOM);
+ params_initialized = true;
+ }
+
+ return button_params;
+}
+
+void LLFavoritesBarCtrl::updateButtons()
+{
+ mItems.clear();
+
+ if (!collectFavoriteItems(mItems))
+ {
+ return;
+ }
+
+ const LLButton::Params& button_params = getButtonParams();
+
+ if(mItems.empty())
+ {
+ mBarLabel->setVisible(TRUE);
+ }
+ else
+ {
+ mBarLabel->setVisible(FALSE);
+ }
+ const child_list_t* childs = getChildList();
+ child_list_const_iter_t child_it = childs->begin();
+ int first_changed_item_index = 0;
+ int rightest_point = getRect().mRight - mMoreTextBox->getRect().getWidth();
+ //lets find first changed button
+ while (child_it != childs->end() && first_changed_item_index < mItems.size())
+ {
+ LLFavoriteLandmarkButton* button = dynamic_cast (*child_it);
+ if (button)
+ {
+ const LLViewerInventoryItem *item = mItems[first_changed_item_index].get();
+ if (item)
+ {
+ // an child's order and mItems should be same
+ if (button->getLandmarkId() != item->getUUID() // sort order has been changed
+ || button->getLabelSelected() != item->getName() // favorite's name has been changed
+ || button->getRect().mRight < rightest_point) // favbar's width has been changed
+ {
+ break;
+ }
+ }
+ first_changed_item_index++;
+ }
+ child_it++;
+ }
+ // now first_changed_item_index should contains a number of button that need to change
+
+ if (first_changed_item_index <= mItems.size())
+ {
+ // Rebuild the buttons only
+ // child_list_t is a linked list, so safe to erase from the middle if we pre-increment the iterator
+
+ while (child_it != childs->end())
+ {
+ //lets remove other landmarks button and rebuild it
+ child_list_const_iter_t cur_it = child_it++;
+ LLFavoriteLandmarkButton* button =
+ dynamic_cast (*cur_it);
+ if (button)
+ {
+ removeChild(button);
+ delete button;
+ }
+ }
+ // we have to remove ChevronButton to make sure that the last item will be LandmarkButton to get the right aligning
+ // keep in mind that we are cutting all buttons in space between the last visible child of favbar and ChevronButton
+ if (mMoreTextBox->getParent() == this)
+ {
+ removeChild(mMoreTextBox);
+ }
+ int last_right_edge = 0;
+ //calculate new buttons offset
+ if (getChildList()->size() > 0)
+ {
+ //find last visible child to get the rightest button offset
+ child_list_const_reverse_iter_t last_visible_it = std::find_if(childs->rbegin(), childs->rend(),
+ std::mem_fn(&LLView::getVisible));
+ if(last_visible_it != childs->rend())
+ {
+ last_right_edge = (*last_visible_it)->getRect().mRight;
+ }
+ }
+ //last_right_edge is saving coordinates
+ LLButton* last_new_button = NULL;
+ int j = first_changed_item_index;
+ for (; j < mItems.size(); j++)
+ {
+ last_new_button = createButton(mItems[j], button_params, last_right_edge);
+ if (!last_new_button)
+ {
+ break;
+ }
+ sendChildToBack(last_new_button);
+ last_right_edge = last_new_button->getRect().mRight;
+
+ mLastTab = last_new_button;
+ }
+ mFirstDropDownItem = j;
+ // Chevron button
+ if (mFirstDropDownItem < mItems.size())
+ {
+ // if updateButton had been called it means:
+ //or there are some new favorites, or width had been changed
+ // so if we need to display chevron button, we must update dropdown items too.
+ mUpdateDropDownItems = true;
+ S32 buttonHGap = button_params.rect.left; // default value
+ LLRect rect;
+ // Chevron button should stay right aligned
+ rect.setOriginAndSize(getRect().mRight - mMoreTextBox->getRect().getWidth() - buttonHGap, 0,
+ mMoreTextBox->getRect().getWidth(),
+ mMoreTextBox->getRect().getHeight());
+
+ addChild(mMoreTextBox);
+ mMoreTextBox->setRect(rect);
+ mMoreTextBox->setVisible(TRUE);
+ }
+ // Update overflow menu
+ LLMenuGL* overflow_menu = static_cast (mOverflowMenuHandle.get());
+ if (overflow_menu && overflow_menu->getVisible() && (overflow_menu->getItemCount() != mDropDownItemsCount))
+ {
+ overflow_menu->setVisible(FALSE);
+ if (mUpdateDropDownItems)
+ {
+ showDropDownMenu();
+ }
+ }
+ }
+ else
+ {
+ mUpdateDropDownItems = false;
+ }
+
+}
+
+LLButton* LLFavoritesBarCtrl::createButton(const LLPointer item, const LLButton::Params& button_params, S32 x_offset)
+{
+ S32 def_button_width = button_params.rect.width;
+ S32 button_x_delta = button_params.rect.left; // default value
+ S32 curr_x = x_offset;
+
+ /**
+ * WORKAROUND:
+ * There are some problem with displaying of fonts in buttons.
+ * Empty space or ellipsis might be displayed instead of last symbols, even though the width of the button is enough.
+ * The problem disappears if we pad the button with 20 pixels.
+ */
+ int required_width = mFont->getWidth(item->getName()) + 20;
+ int width = required_width > def_button_width? def_button_width : required_width;
+ LLFavoriteLandmarkButton* fav_btn = NULL;
+
+ // do we have a place for next button + double buttonHGap + mMoreTextBox ?
+ if(curr_x + width + 2*button_x_delta + mMoreTextBox->getRect().getWidth() > getRect().mRight )
+ {
+ return NULL;
+ }
+ LLButton::Params fav_btn_params(button_params);
+ fav_btn = new LLFavoriteLandmarkButton(fav_btn_params);
+ if (NULL == fav_btn)
+ {
+ LL_WARNS("FavoritesBar") << "Unable to create LLFavoriteLandmarkButton widget: " << item->getName() << LL_ENDL;
+ return NULL;
+ }
+
+ addChild(fav_btn);
+
+ LLRect butt_rect (fav_btn->getRect());
+ fav_btn->setLandmarkID(item->getUUID());
+ butt_rect.setOriginAndSize(curr_x + button_x_delta, fav_btn->getRect().mBottom, width, fav_btn->getRect().getHeight());
+
+ fav_btn->setRect(butt_rect);
+ // change only left and save bottom
+ fav_btn->setFont(mFont);
+ fav_btn->setLabel(item->getName());
+ fav_btn->setToolTip(item->getName());
+ fav_btn->setCommitCallback(boost::bind(&LLFavoritesBarCtrl::onButtonClick, this, item->getUUID()));
+ fav_btn->setRightMouseDownCallback(boost::bind(&LLFavoritesBarCtrl::onButtonRightClick, this, item->getUUID(), _1, _2, _3,_4 ));
+
+ fav_btn->LLUICtrl::setMouseDownCallback(boost::bind(&LLFavoritesBarCtrl::onButtonMouseDown, this, item->getUUID(), _1, _2, _3, _4));
+ fav_btn->LLUICtrl::setMouseUpCallback(boost::bind(&LLFavoritesBarCtrl::onButtonMouseUp, this, item->getUUID(), _1, _2, _3, _4));
+
+ return fav_btn;
+}
+
+
+BOOL LLFavoritesBarCtrl::postBuild()
+{
+ // make the popup menu available
+ LLMenuGL* menu = LLUICtrlFactory::getInstance()->buildMenu("menu_favorites.xml", gMenuHolder);
+ if (!menu)
+ {
+ return FALSE; //menu = LLUICtrlFactory::getDefaultWidget("inventory_menu");
+ }
+ menu->setBackgroundColor(gColors.getColor("MenuPopupBgColor"));
+ mContextMenuHandle = menu->getHandle();
+
+ return TRUE;
+}
+
+BOOL collectFavoriteItems(LLInventoryModel::item_array_t& items)
+{
+
+ auto mFavoriteFolderId = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
+ if (mFavoriteFolderId.isNull())
+ return FALSE;
+
+
+ LLInventoryModel::cat_array_t cats;
+
+ LLIsType is_type(LLAssetType::AT_LANDMARK);
+ gInventory.collectDescendentsIf(mFavoriteFolderId, cats, items, LLInventoryModel::EXCLUDE_TRASH, is_type);
+
+ std::sort(items.begin(), items.end(), LLFavoritesSort());
+
+ BOOL needToSaveItemsOrder(const LLInventoryModel::item_array_t& items);
+ //if (needToSaveItemsOrder(items))
+ {
+ S32 sortField = 0;
+ for (LLInventoryModel::item_array_t::iterator i = items.begin(); i != items.end(); ++i)
+ {
+ LLFavoritesOrderStorage::instance().setSortIndex((*i), ++sortField);
+ }
+ }
+
+ return TRUE;
+}
+BOOL LLFavoritesBarCtrl::collectFavoriteItems(LLInventoryModel::item_array_t& items) { return ::collectFavoriteItems(items); }
+
+void LLFavoritesBarCtrl::showDropDownMenu()
+{
+ if (mOverflowMenuHandle.isDead())
+ {
+ createOverflowMenu();
+ }
+
+ LLMenuGL* menu = (LLMenuGL*)mOverflowMenuHandle.get();
+ if (menu)
+ {
+
+ if (mUpdateDropDownItems)
+ {
+ updateMenuItems(menu);
+ }
+
+ menu->buildDrawLabels();
+ menu->updateParent(LLMenuGL::sMenuContainer);
+ //menu->setButtonRect(mMoreTextBox->getRect(), this);
+ positionAndShowMenu(menu);
+ mDropDownItemsCount = menu->getItemCount();
+ }
+}
+
+void LLFavoritesBarCtrl::createOverflowMenu()
+{
+ LLMenuGL* menu = new LLFavoriteLandmarkToggleableMenu();
+ menu->setCanTearOff(false);
+ menu->setVisible(false);
+ menu->setScrollable(true);
+ //menu_p.max_scrollable_items = 10;
+ //menu_p.preferred_width = DROP_DOWN_MENU_WIDTH;
+ mOverflowMenuHandle = menu->getHandle();
+}
+
+void LLFavoritesBarCtrl::updateMenuItems(LLMenuGL* menu)
+{
+ menu->empty();
+
+ U32 widest_item = 0;
+
+ for (S32 i = mFirstDropDownItem; i < mItems.size(); i++)
+ {
+ LLViewerInventoryItem* item = mItems.at(i);
+ const std::string& item_name = item->getName();
+
+ LLFavoriteLandmarkMenuItem::Params item_params;
+ item_params.name(item_name);
+ item_params.label(item_name);
+
+ LLFavoriteLandmarkMenuItem *menu_item = new LLFavoriteLandmarkMenuItem(item_params);
+ menu_item->setMouseUpCallback(std::bind(&LLFavoritesBarCtrl::onButtonClick, this, item->getUUID()));
+ menu_item->initFavoritesBarPointer(this);
+ menu_item->setRightMouseDownCallback(boost::bind(&LLFavoritesBarCtrl::onButtonRightClick, this, item->getUUID(), _1, _2, _3, _4));
+ menu_item->LLUICtrl::setMouseDownCallback(boost::bind(&LLFavoritesBarCtrl::onButtonMouseDown, this, item->getUUID(), _1, _2, _3, _4));
+ menu_item->LLUICtrl::setMouseUpCallback(boost::bind(&LLFavoritesBarCtrl::onButtonMouseUp, this, item->getUUID(), _1, _2, _3, _4));
+ menu_item->setLandmarkID(item->getUUID());
+
+ fitLabelWidth(menu_item);
+
+ widest_item = llmax(widest_item, menu_item->getNominalWidth());
+
+ menu->addChild(menu_item);
+ }
+
+ addOpenLandmarksMenuItem(menu);
+ mUpdateDropDownItems = false;
+}
+
+void LLFavoritesBarCtrl::fitLabelWidth(LLMenuItemCallGL* menu_item)
+{
+ U32 max_width = llmin(DROP_DOWN_MENU_WIDTH, getRect().getWidth());
+ std::string item_name = menu_item->getName();
+
+ // Check whether item name wider than menu
+ if (menu_item->getNominalWidth() > max_width)
+ {
+ S32 chars_total = item_name.length();
+ S32 chars_fitted = 1;
+ menu_item->setLabel(LLStringExplicit(""));
+ S32 label_space = max_width - menu_item->getFont()->getWidth("...") -
+ menu_item->getNominalWidth();// This returns width of menu item with empty label (pad pixels)
+
+ while (chars_fitted < chars_total
+ && menu_item->getFont()->getWidth(item_name, 0, chars_fitted) < label_space)
+ {
+ chars_fitted++;
+ }
+ chars_fitted--; // Rolling back one char, that doesn't fit
+
+ menu_item->setLabel(item_name.substr(0, chars_fitted) + "...");
+ }
+}
+
+void LLFavoritesBarCtrl::addOpenLandmarksMenuItem(LLMenuGL* menu)
+{
+ std::string label_untrans = "Open landmarks";
+ std::string label_transl;
+ bool translated = LLTrans::findString(label_transl, label_untrans);
+
+ LLMenuItemCallGL* menu_item = new LLMenuItemCallGL(std::string("open_my_landmarks"), std::string(translated ? label_transl : label_untrans), nullptr);
+ void show_floater(const std::string& floater_name);
+ menu_item->setMouseUpCallback(std::bind(show_floater, "floater_inventory_favs.xml"));
+
+ fitLabelWidth(menu_item);
+
+ LLMenuItemSeparatorGL* separator = new LLMenuItemSeparatorGL;
+
+ menu->addChild(separator);
+ menu->addChild(menu_item);
+}
+
+void LLFavoritesBarCtrl::positionAndShowMenu(LLMenuGL* menu)
+{
+ U32 max_width = llmin(DROP_DOWN_MENU_WIDTH, getRect().getWidth());
+
+ S32 menu_x = getRect().getWidth() - max_width;
+ S32 menu_y = getParent()->getRect().mBottom - DROP_DOWN_MENU_TOP_PAD;
+
+ /* Singu TODO: Side Toolbar?
+ // the menu should be offset of the right edge of the window
+ // so it's no covered by buttons in the right-side toolbar.
+ LLToolBar* right_toolbar = gToolBarView->getChild("toolbar_right");
+ if (right_toolbar && right_toolbar->hasButtons())
+ {
+ S32 toolbar_top = 0;
+
+ if (LLView* top_border_panel = right_toolbar->getChild("button_panel"))
+ {
+ toolbar_top = top_border_panel->calcScreenRect().mTop;
+ }
+
+ // Calculating the bottom (in screen coord) of the drop down menu
+ S32 menu_top = getParent()->getRect().mBottom - DROP_DOWN_MENU_TOP_PAD;
+ S32 menu_bottom = menu_top - menu->getRect().getHeight();
+ S32 menu_bottom_screen = 0;
+
+ localPointToScreen(0, menu_bottom, &menu_top, &menu_bottom_screen);
+
+ if (menu_bottom_screen < toolbar_top)
+ {
+ menu_x -= right_toolbar->getRect().getWidth();
+ }
+ }
+ */
+
+ LLMenuGL::showPopup(this, menu, menu_x, menu_y);
+}
+
+void LLFavoritesBarCtrl::onButtonClick(LLUUID item_id)
+{
+ // We only have one Inventory, gInventory. Some day this should be better abstracted.
+ LLInvFVBridgeAction::doAction(item_id,&gInventory);
+}
+
+void LLFavoritesBarCtrl::onButtonRightClick( LLUUID item_id,LLView* fav_button,S32 x,S32 y,MASK mask)
+{
+ mSelectedItemID = item_id;
+
+ LLMenuGL* menu = (LLMenuGL*)mContextMenuHandle.get();
+ if (!menu)
+ {
+ return;
+ }
+
+ // Remember that the context menu was shown simultaneously with the overflow menu,
+ // so that we can restore the overflow menu when user clicks a context menu item
+ // (which hides the overflow menu).
+ {
+ LLView* overflow_menu = mOverflowMenuHandle.get();
+ mRestoreOverflowMenu = overflow_menu && overflow_menu->getVisible();
+ }
+
+ // Release mouse capture so hover events go to the popup menu
+ // because this is happening during a mouse down.
+ gFocusMgr.setMouseCapture(NULL);
+
+ menu->updateParent(LLMenuGL::sMenuContainer);
+ LLMenuGL::showPopup(fav_button, menu, x, y);
+}
+
+BOOL LLFavoritesBarCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask)
+{
+ BOOL handled = childrenHandleRightMouseDown( x, y, mask) != NULL;
+ /*if(!handled && !gMenuHolder->hasVisibleMenu())
+ {
+ show_navbar_context_menu(this,x,y);
+ handled = true;
+ }*/
+
+ return handled;
+}
+void copy_slurl_to_clipboard_cb(std::string& slurl)
+{
+ LLView::getWindow()->copyTextToClipboard(utf8str_to_wstring(slurl));
+
+ LLSD args;
+ args["SLURL"] = slurl;
+ LLNotificationsUtil::add("CopySLURL", args);
+}
+
+
+bool LLFavoritesBarCtrl::enableSelected(const LLSD& userdata)
+{
+ std::string param = userdata.asString();
+
+ if (param == std::string("can_paste"))
+ {
+ return isClipboardPasteable();
+ }
+
+ return false;
+}
+
+void LLFavoritesBarCtrl::doToSelected(const LLSD& userdata)
+{
+ std::string action = userdata.asString();
+ LL_INFOS("FavoritesBar") << "Action = " << action << " Item = " << mSelectedItemID.asString() << LL_ENDL;
+
+ LLViewerInventoryItem* item = gInventory.getItem(mSelectedItemID);
+ if (!item)
+ return;
+
+ if (action == "open")
+ {
+ onButtonClick(item->getUUID());
+ }
+ else if (action == "about")
+ {
+ LLSD key;
+ key["type"] = "landmark";
+ key["id"] = mSelectedItemID;
+
+ open_landmark(item, "Favorite", false, mSelectedItemID, true);
+ }
+ else if (action == "copy_slurl")
+ {
+ LLVector3d posGlobal;
+ LLLandmarkActions::getLandmarkGlobalPos(mSelectedItemID, posGlobal);
+
+ if (!posGlobal.isExactlyZero())
+ {
+ LLLandmarkActions::getSLURLfromPosGlobal(posGlobal, copy_slurl_to_clipboard_cb);
+ }
+ }
+ else if (action == "show_on_map")
+ {
+ LLFloaterWorldMap* worldmap_instance = gFloaterWorldMap;
+
+ LLVector3d posGlobal;
+ LLLandmarkActions::getLandmarkGlobalPos(mSelectedItemID, posGlobal);
+
+ if (!posGlobal.isExactlyZero() && worldmap_instance)
+ {
+ worldmap_instance->trackLocation(posGlobal);
+ LLFloaterWorldMap::show(true);
+ }
+ }
+ else if (action == "cut")
+ {
+ }
+ else if (action == "copy")
+ {
+ LLInventoryClipboard::instance().add(mSelectedItemID);
+ }
+ else if (action == "paste")
+ {
+ pasteFromClipboard();
+ }
+ else if (action == "delete")
+ {
+ gInventory.removeItem(mSelectedItemID);
+ }
+
+ // Pop-up the overflow menu again (it gets hidden whenever the user clicks a context menu item).
+ // See EXT-4217 and STORM-207.
+ LLMenuGL* menu = (LLMenuGL*) mOverflowMenuHandle.get();
+ if (mRestoreOverflowMenu && menu && !menu->getVisible())
+ {
+ menu->resetScrollPositionOnShow(false);
+ showDropDownMenu();
+ menu->resetScrollPositionOnShow(true);
+ }
+}
+
+BOOL LLFavoritesBarCtrl::isClipboardPasteable() const
+{
+ if (!LLInventoryClipboard::instance().hasContents())
+ {
+ return FALSE;
+ }
+
+ std::vector objects;
+ LLInventoryClipboard::instance().retrieve(objects);
+ S32 count = objects.size();
+ for(S32 i = 0; i < count; i++)
+ {
+ const LLUUID &item_id = objects.at(i);
+
+ // Can't paste folders
+ const LLInventoryCategory *cat = gInventory.getCategory(item_id);
+ if (cat)
+ {
+ return FALSE;
+ }
+
+ const LLInventoryItem *item = gInventory.getItem(item_id);
+ if (item && LLAssetType::AT_LANDMARK != item->getType())
+ {
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+void LLFavoritesBarCtrl::pasteFromClipboard() const
+{
+ LLInventoryModel* model = &gInventory;
+ if(model && isClipboardPasteable())
+ {
+ LLInventoryItem* item = NULL;
+ std::vector objects;
+ LLInventoryClipboard::instance().retrieve(objects);
+ S32 count = objects.size();
+ LLUUID parent_id(mFavoriteFolderId);
+ for(S32 i = 0; i < count; i++)
+ {
+ item = model->getItem(objects.at(i));
+ if (item)
+ {
+ copy_inventory_item(
+ gAgent.getID(),
+ item->getPermissions().getOwner(),
+ item->getUUID(),
+ parent_id,
+ std::string(),
+ LLPointer(NULL));
+ }
+ }
+ }
+}
+
+void LLFavoritesBarCtrl::onButtonMouseDown(LLUUID id, LLUICtrl* ctrl, S32 x, S32 y, MASK mask)
+{
+ // EXT-6997 (Fav bar: Pop-up menu for LM in overflow dropdown is kept after LM was dragged away)
+ // mContextMenuHandle.get() - is a pop-up menu (of items) in already opened dropdown menu.
+ // We have to check and set visibility of pop-up menu in such a way instead of using
+ // LLMenuHolderGL::hideMenus() because it will close both menus(dropdown and pop-up), but
+ // we need to close only pop-up menu while dropdown one should be still opened.
+ LLMenuGL* menu = (LLMenuGL*)mContextMenuHandle.get();
+ if(menu && menu->getVisible())
+ {
+ menu->setVisible(FALSE);
+ }
+
+ mDragItemId = id;
+ mStartDrag = TRUE;
+
+ S32 screenX, screenY;
+ localPointToScreen(x, y, &screenX, &screenY);
+
+ LLToolDragAndDrop::getInstance()->setDragStart(screenX, screenY);
+}
+
+void LLFavoritesBarCtrl::onButtonMouseUp(LLUUID id, LLUICtrl* ctrl, S32 x, S32 y, MASK mask)
+{
+ mStartDrag = FALSE;
+ mDragItemId = LLUUID::null;
+}
+
+void LLFavoritesBarCtrl::onEndDrag()
+{
+ mEndDragConnection.disconnect();
+
+ showDragMarker(FALSE);
+ mDragItemId = LLUUID::null;
+ LLView::getWindow()->setCursor(UI_CURSOR_ARROW);
+}
+
+BOOL LLFavoritesBarCtrl::handleHover(S32 x, S32 y, MASK mask)
+{
+ if (mDragItemId != LLUUID::null && mStartDrag)
+ {
+ S32 screenX, screenY;
+ localPointToScreen(x, y, &screenX, &screenY);
+
+ if(LLToolDragAndDrop::getInstance()->isOverThreshold(screenX, screenY))
+ {
+ LLToolDragAndDrop::getInstance()->beginDrag(
+ DAD_LANDMARK, mDragItemId,
+ LLToolDragAndDrop::SOURCE_LIBRARY);
+
+ mStartDrag = FALSE;
+
+ return LLToolDragAndDrop::getInstance()->handleHover(x, y, mask);
+ }
+ }
+
+ return TRUE;
+}
+
+LLUICtrl* LLFavoritesBarCtrl::findChildByLocalCoords(S32 x, S32 y)
+{
+ LLUICtrl* ctrl = NULL;
+ const child_list_t* list = getChildList();
+
+ for (child_list_const_iter_t i = list->begin(); i != list->end(); ++i)
+ {
+ // Look only for children that are favorite buttons
+ if ((*i)->getName() == "favorites_bar_btn")
+ {
+ LLRect rect = (*i)->getRect();
+ // We consider a button hit if the cursor is left of the right side
+ // This makes the hit a bit less finicky than hitting directly on the button itself
+ if (x <= rect.mRight)
+ {
+ ctrl = dynamic_cast(*i);
+ break;
+ }
+ }
+ }
+ return ctrl;
+}
+
+BOOL needToSaveItemsOrder(const LLInventoryModel::item_array_t& items)
+{
+ BOOL result = FALSE;
+
+ // if there is an item without sort order field set, we need to save items order
+ for (LLInventoryModel::item_array_t::const_iterator i = items.begin(); i != items.end(); ++i)
+ {
+ if (LLFavoritesOrderStorage::instance().getSortIndex((*i)->getUUID()) < 0)
+ {
+ result = TRUE;
+ break;
+ }
+ }
+
+ return result;
+}
+BOOL LLFavoritesBarCtrl::needToSaveItemsOrder(const LLInventoryModel::item_array_t& items) { return ::needToSaveItemsOrder(items); }
+
+void LLFavoritesBarCtrl::insertItem(LLInventoryModel::item_array_t& items, const LLUUID& dest_item_id, LLViewerInventoryItem* insertedItem, bool insert_before)
+{
+ // Get the iterator to the destination item
+ LLInventoryModel::item_array_t::iterator it_dest = LLInventoryModel::findItemIterByUUID(items, dest_item_id);
+ if (it_dest == items.end())
+ return;
+
+ // Go to the next element if one wishes to insert after the dest element
+ if (!insert_before)
+ {
+ ++it_dest;
+ }
+
+ // Insert the source item in the right place
+ if (it_dest != items.end())
+ {
+ items.insert(it_dest, insertedItem);
+ }
+ else
+ {
+ // Append to the list if it_dest reached the end
+ items.push_back(insertedItem);
+ }
+}
+
+const std::string LLFavoritesOrderStorage::SORTING_DATA_FILE_NAME = "landmarks_sorting.xml";
+const S32 LLFavoritesOrderStorage::NO_INDEX = -1;
+
+void LLFavoritesOrderStorage::setSortIndex(const LLViewerInventoryItem* inv_item, S32 sort_index)
+{
+ mSortIndexes[inv_item->getUUID()] = sort_index;
+ mIsDirty = true;
+ getSLURL(inv_item->getAssetUUID());
+}
+
+S32 LLFavoritesOrderStorage::getSortIndex(const LLUUID& inv_item_id)
+{
+ sort_index_map_t::const_iterator it = mSortIndexes.find(inv_item_id);
+ if (it != mSortIndexes.end())
+ {
+ return it->second;
+ }
+ return NO_INDEX;
+}
+
+void LLFavoritesOrderStorage::removeSortIndex(const LLUUID& inv_item_id)
+{
+ mSortIndexes.erase(inv_item_id);
+ mIsDirty = true;
+}
+
+void LLFavoritesOrderStorage::getSLURL(const LLUUID& asset_id)
+{
+ slurls_map_t::iterator slurl_iter = mSLURLs.find(asset_id);
+ if (slurl_iter != mSLURLs.end()) return; // SLURL for current landmark is already cached
+
+ LLLandmark* lm = gLandmarkList.getAsset(asset_id,
+ boost::bind(&LLFavoritesOrderStorage::onLandmarkLoaded, this, asset_id, _1));
+ if (lm)
+ {
+ LL_DEBUGS("FavoritesBar") << "landmark for " << asset_id << " already loaded" << LL_ENDL;
+ onLandmarkLoaded(asset_id, lm);
+ }
+}
+
+// static
+std::string LLFavoritesOrderStorage::getStoredFavoritesFilename()
+{
+ std::string user_dir = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "");
+
+ return (user_dir.empty() ? ""
+ : gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS,
+ "stored_favorites_"
+ + gHippoGridManager->getCurrentGridName()
+ + ".xml")
+ );
+}
+
+// static
+void LLFavoritesOrderStorage::destroyClass()
+{
+ LLFavoritesOrderStorage::instance().cleanup();
+
+
+ std::string old_filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "stored_favorites.xml");
+ llifstream file;
+ file.open(old_filename.c_str());
+ if (file.is_open())
+ {
+ file.close();
+ std::string new_filename = getStoredFavoritesFilename();
+ LL_INFOS("FavoritesBar") << "moving favorites from old name '" << old_filename
+ << "' to new name '" << new_filename << "'"
+ << LL_ENDL;
+ LLFile::rename(old_filename,new_filename);
+ }
+
+ if (gSavedPerAccountSettings.getBOOL("ShowFavoritesOnLogin"))
+ {
+ LLFavoritesOrderStorage::instance().saveFavoritesSLURLs();
+ }
+ else
+ {
+ LLFavoritesOrderStorage::instance().removeFavoritesRecordOfUser();
+ }
+}
+
+std::string LLFavoritesOrderStorage::getSavedOrderFileName()
+{
+ // If we quit from the login screen we will not have an SL account
+ // name. Don't try to save, otherwise we'll dump a file in
+ // C:\Program Files\SecondLife\ or similar. JC
+ std::string user_dir = gDirUtilp->getLindenUserDir();
+ return (user_dir.empty() ? "" : gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, SORTING_DATA_FILE_NAME));
+}
+
+void LLFavoritesOrderStorage::load()
+{
+ // load per-resident sorting information
+ std::string filename = getSavedOrderFileName();
+ LLSD settings_llsd;
+ llifstream file;
+ file.open(filename.c_str());
+ if (file.is_open())
+ {
+ LLSDSerialize::fromXML(settings_llsd, file);
+ LL_INFOS("FavoritesBar") << "loaded favorites order from '" << filename << "' "
+ << (settings_llsd.isMap() ? "" : "un") << "successfully"
+ << LL_ENDL;
+ file.close();
+ }
+ else
+ {
+ LL_WARNS("FavoritesBar") << "unable to open favorites order file at '" << filename << "'" << LL_ENDL;
+ }
+
+ for (LLSD::map_const_iterator iter = settings_llsd.beginMap();
+ iter != settings_llsd.endMap(); ++iter)
+ {
+ mSortIndexes.insert(std::make_pair(LLUUID(iter->first), (S32)iter->second.asInteger()));
+ }
+}
+
+void LLFavoritesOrderStorage::saveFavoritesSLURLs()
+{
+ // Do not change the file if we are not logged in yet.
+ if (gAgentID.isNull()) //LLLoginInstance::getInstance()->authSuccess())
+ {
+ LL_WARNS("FavoritesBar") << "Cannot save favorites: not logged in" << LL_ENDL;
+ return;
+ }
+
+ std::string filename = getStoredFavoritesFilename();
+ if (!filename.empty())
+ {
+ llifstream in_file;
+ in_file.open(filename.c_str());
+ LLSD fav_llsd;
+ if (in_file.is_open())
+ {
+ LLSDSerialize::fromXML(fav_llsd, in_file);
+ LL_INFOS("FavoritesBar") << "loaded favorites from '" << filename << "' "
+ << (fav_llsd.isMap() ? "" : "un") << "successfully"
+ << LL_ENDL;
+ in_file.close();
+ }
+ else
+ {
+ LL_WARNS("FavoritesBar") << "unable to open favorites from '" << filename << "'" << LL_ENDL;
+ }
+
+ const LLUUID fav_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
+ LLInventoryModel::cat_array_t cats;
+ LLInventoryModel::item_array_t items;
+ gInventory.collectDescendents(fav_id, cats, items, LLInventoryModel::EXCLUDE_TRASH);
+
+ LLSD user_llsd;
+ for (LLInventoryModel::item_array_t::const_iterator it = items.cbegin(); it != items.cend(); ++it)
+ {
+ if (it->get()->getActualType() != LLAssetType::AT_LANDMARK) continue;
+ LLSD value;
+ value["name"] = (*it)->getName();
+ value["asset_id"] = (*it)->getAssetUUID();
+
+ slurls_map_t::const_iterator slurl_iter = mSLURLs.find(value["asset_id"]);
+ if (slurl_iter != mSLURLs.cend())
+ {
+ LL_DEBUGS("FavoritesBar") << "Saving favorite: idx=" << LLFavoritesOrderStorage::instance().getSortIndex((*it)->getUUID())
+ << ", SLURL=" << slurl_iter->second
+ << ", value=" << value << LL_ENDL;
+ value["slurl"] = slurl_iter->second;
+ user_llsd[LLFavoritesOrderStorage::instance().getSortIndex((*it)->getUUID())] = value;
+ }
+ else
+ {
+ LL_WARNS("FavoritesBar") << "Not saving favorite " << value["name"] << ": no matching SLURL" << LL_ENDL;
+ }
+ }
+
+ LLAvatarName av_name;
+ LLAvatarNameCache::get( gAgentID, &av_name );
+ // Note : use the "John Doe" and not the "john.doe" version of the name
+ // as we'll compare it with the stored credentials in the login panel.
+ fav_llsd[av_name.getUserName()] = user_llsd;
+
+ llofstream file;
+ file.open(filename.c_str());
+ if ( file.is_open() )
+ {
+ LLSDSerialize::toPrettyXML(fav_llsd, file);
+ LL_INFOS("FavoritesBar") << "saved favorites for '" << av_name.getUserName()
+ << "' to '" << filename << "' "
+ << LL_ENDL;
+ file.close();
+ }
+ else
+ {
+ LL_WARNS("FavoritesBar") << "unable to open favorites storage for '" << av_name.getUserName()
+ << "' at '" << filename << "' "
+ << LL_ENDL;
+ }
+ }
+}
+
+void LLFavoritesOrderStorage::removeFavoritesRecordOfUser()
+{
+ std::string filename = getStoredFavoritesFilename();
+ if (!filename.empty())
+ {
+ LLSD fav_llsd;
+ llifstream file;
+ file.open(filename.c_str());
+ if (file.is_open())
+ {
+ LLSDSerialize::fromXML(fav_llsd, file);
+ file.close();
+
+ LLAvatarName av_name;
+ LLAvatarNameCache::get( gAgentID, &av_name );
+ // Note : use the "John Doe" and not the "john.doe" version of the name.
+ // See saveFavoritesSLURLs() here above for the reason why.
+ if (fav_llsd.has(av_name.getUserName()))
+ {
+ LL_INFOS("FavoritesBar") << "Removed favorites for " << av_name.getUserName() << LL_ENDL;
+ fav_llsd.erase(av_name.getUserName());
+ }
+
+ llofstream out_file;
+ out_file.open(filename.c_str());
+ if ( out_file.is_open() )
+ {
+ LLSDSerialize::toPrettyXML(fav_llsd, out_file);
+ LL_INFOS("FavoritesBar") << "saved favorites to '" << filename << "' "
+ << LL_ENDL;
+ out_file.close();
+ }
+ }
+ }
+}
+
+void LLFavoritesOrderStorage::onLandmarkLoaded(const LLUUID& asset_id, LLLandmark* landmark)
+{
+ if (landmark)
+ {
+ LL_DEBUGS("FavoritesBar") << "landmark for " << asset_id << " loaded" << LL_ENDL;
+ LLVector3d pos_global;
+ if (!landmark->getGlobalPos(pos_global))
+ {
+ // If global position was unknown on first getGlobalPos() call
+ // it should be set for the subsequent calls.
+ landmark->getGlobalPos(pos_global);
+ }
+
+ if (!pos_global.isExactlyZero())
+ {
+ LL_DEBUGS("FavoritesBar") << "requesting slurl for landmark " << asset_id << LL_ENDL;
+ LLLandmarkActions::getSLURLfromPosGlobal(pos_global,
+ boost::bind(&LLFavoritesOrderStorage::storeFavoriteSLURL, this, asset_id, _1));
+ }
+ }
+}
+
+void LLFavoritesOrderStorage::storeFavoriteSLURL(const LLUUID& asset_id, std::string& slurl)
+{
+ LL_DEBUGS("FavoritesBar") << "Saving landmark SLURL '" << slurl << "' for " << asset_id << LL_ENDL;
+ mSLURLs[asset_id] = slurl;
+}
+
+void LLFavoritesOrderStorage::save()
+{
+ if (mIsDirty)
+ {
+ // something changed, so save it
+ std::string filename = LLFavoritesOrderStorage::getInstance()->getSavedOrderFileName();
+ if (!filename.empty())
+ {
+ LLSD settings_llsd;
+
+ for(sort_index_map_t::const_iterator iter = mSortIndexes.begin(); iter != mSortIndexes.end(); ++iter)
+ {
+ settings_llsd[iter->first.asString()] = iter->second;
+ }
+
+ llofstream file;
+ file.open(filename.c_str());
+ if ( file.is_open() )
+ {
+ LLSDSerialize::toPrettyXML(settings_llsd, file);
+ LL_INFOS("FavoritesBar") << "saved favorites order to '" << filename << "' " << LL_ENDL;
+ }
+ else
+ {
+ LL_WARNS("FavoritesBar") << "failed to open favorites order file '" << filename << "' " << LL_ENDL;
+ }
+ }
+ else
+ {
+ LL_DEBUGS("FavoritesBar") << "no user directory available to store favorites order file" << LL_ENDL;
+ }
+ }
+}
+
+
+void LLFavoritesOrderStorage::cleanup()
+{
+ // nothing to clean
+ if (!mIsDirty) return;
+
+ const LLUUID fav_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
+ LLInventoryModel::cat_array_t cats;
+ LLInventoryModel::item_array_t items;
+ gInventory.collectDescendents(fav_id, cats, items, LLInventoryModel::EXCLUDE_TRASH);
+
+ IsNotInFavorites is_not_in_fav(items);
+
+ sort_index_map_t aTempMap;
+ //copy unremoved values from mSortIndexes to aTempMap
+ std::remove_copy_if(mSortIndexes.begin(), mSortIndexes.end(),
+ inserter(aTempMap, aTempMap.begin()),
+ is_not_in_fav);
+
+ //Swap the contents of mSortIndexes and aTempMap
+ mSortIndexes.swap(aTempMap);
+}
+
+// See also LLInventorySort where landmarks in the Favorites folder are sorted.
+class LLViewerInventoryItemSort
+{
+public:
+ bool operator()(const LLPointer& a, const LLPointer& b) const
+ {
+ return LLFavoritesOrderStorage::instance().getSortIndex(a->getUUID())
+ < LLFavoritesOrderStorage::instance().getSortIndex(b->getUUID());
+ }
+};
+
+void LLFavoritesOrderStorage::saveOrder()
+{
+ LLInventoryModel::cat_array_t cats;
+ LLInventoryModel::item_array_t items;
+ LLIsType is_type(LLAssetType::AT_LANDMARK);
+ LLUUID favorites_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
+ gInventory.collectDescendentsIf(favorites_id, cats, items, LLInventoryModel::EXCLUDE_TRASH, is_type);
+ std::sort(items.begin(), items.end(), LLViewerInventoryItemSort());
+ saveItemsOrder(items);
+}
+
+void LLFavoritesOrderStorage::saveItemsOrder( const LLInventoryModel::item_array_t& items )
+{
+
+ int sortField = 0;
+ // current order is saved by setting incremental values (1, 2, 3, ...) for the sort field
+ for (LLInventoryModel::item_array_t::const_iterator i = items.begin(); i != items.end(); ++i)
+ {
+ LLViewerInventoryItem* item = *i;
+
+ setSortIndex(item, ++sortField);
+
+ item->setComplete(TRUE);
+ item->updateServer(FALSE);
+
+ gInventory.updateItem(item);
+
+ // Tell the parent folder to refresh its sort order.
+ gInventory.addChangedMask(LLInventoryObserver::SORT, item->getParentUUID());
+ }
+
+ gInventory.notifyObservers();
+}
+
+
+// * @param source_item_id - LLUUID of the source item to be moved into new position
+// * @param target_item_id - LLUUID of the target item before which source item should be placed.
+void LLFavoritesOrderStorage::rearrangeFavoriteLandmarks(const LLUUID& source_item_id, const LLUUID& target_item_id)
+{
+ LLInventoryModel::cat_array_t cats;
+ LLInventoryModel::item_array_t items;
+ //LLIsType is_type(LLAssetType::AT_LANDMARK); // Singu Note: We can have anything here~
+ LLUUID favorites_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
+ gInventory.collectDescendents(favorites_id, cats, items, LLInventoryModel::EXCLUDE_TRASH/*, is_type*/);
+
+ // ensure items are sorted properly before changing order. EXT-3498
+ std::sort(items.begin(), items.end(), LLViewerInventoryItemSort());
+
+ // update order
+ gInventory.updateItemsOrder(items, source_item_id, target_item_id);
+
+ saveItemsOrder(items);
+}
+
+void AddFavoriteLandmarkCallback::fire(const LLUUID& inv_item_id)
+{
+ if (mTargetLandmarkId.isNull()) return;
+
+ LLFavoritesOrderStorage::instance().rearrangeFavoriteLandmarks(inv_item_id, mTargetLandmarkId);
+}
+// EOF
diff --git a/indra/newview/llfavoritesbar.h b/indra/newview/llfavoritesbar.h
new file mode 100644
index 000000000..ef6f55c5e
--- /dev/null
+++ b/indra/newview/llfavoritesbar.h
@@ -0,0 +1,274 @@
+/**
+ * @file llfavoritesbar.h
+ * @brief LLFavoritesBarCtrl base class
+ *
+ * $LicenseInfo:firstyear=2009&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLFAVORITESBARCTRL_H
+#define LL_LLFAVORITESBARCTRL_H
+
+#include "llbutton.h"
+#include "lluictrl.h"
+#include "lltextbox.h"
+
+#include "llinventoryobserver.h"
+#include "llinventorymodel.h"
+#include "llviewerinventory.h"
+#include "llui.h" //"llinitdestroyclass.h"
+
+class LLMenuItemCallGL;
+class LLMenuGL;
+
+class LLFavoritesBarCtrl : public LLUICtrl, public LLInventoryObserver
+{
+public:
+ struct Params : public LLInitParam::Block
+ {
+ Optional image_drag_indication;
+ Optional more_button;
+ Optional label;
+ Params();
+ };
+
+protected:
+ LLFavoritesBarCtrl(const Params&);
+ friend class LLUICtrlFactory;
+public:
+ virtual ~LLFavoritesBarCtrl();
+
+ /*virtual*/ BOOL postBuild() override;
+
+ /*virtual*/ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
+ EDragAndDropType cargo_type,
+ void* cargo_data,
+ EAcceptance* accept,
+ std::string& tooltip_msg) override;
+
+ /*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask) override;
+ /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask) override;
+ // LLInventoryObserver observer trigger
+ void changed(U32 mask) override;
+ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE) override;
+ void draw() override;
+
+ void showDragMarker(BOOL show) { mShowDragMarker = show; }
+ void setLandingTab(LLUICtrl* tab) { mLandingTab = tab; }
+
+protected:
+ void updateButtons();
+ LLButton* createButton(const LLPointer item, const LLButton::Params& button_params, S32 x_offset );
+ const LLButton::Params& getButtonParams();
+ BOOL collectFavoriteItems(LLInventoryModel::item_array_t &items);
+
+ void onButtonClick(LLUUID id);
+ void onButtonRightClick(LLUUID id,LLView* button,S32 x,S32 y,MASK mask);
+
+ void onButtonMouseDown(LLUUID id, LLUICtrl* button, S32 x, S32 y, MASK mask);
+ void onOverflowMenuItemMouseDown(LLUUID id, LLUICtrl* item, S32 x, S32 y, MASK mask);
+ void onButtonMouseUp(LLUUID id, LLUICtrl* button, S32 x, S32 y, MASK mask);
+
+ void onEndDrag();
+
+ bool enableSelected(const LLSD& userdata);
+ void doToSelected(const LLSD& userdata);
+ BOOL isClipboardPasteable() const;
+ void pasteFromClipboard() const;
+
+ void showDropDownMenu();
+
+ LLHandle mOverflowMenuHandle;
+ LLHandle mContextMenuHandle;
+
+ LLUUID mFavoriteFolderId;
+ const LLFontGL *mFont;
+ S32 mFirstDropDownItem;
+ S32 mDropDownItemsCount;
+ bool mUpdateDropDownItems;
+ bool mRestoreOverflowMenu;
+
+ LLUUID mSelectedItemID;
+
+ LLUIImage* mImageDragIndication;
+
+private:
+ /*
+ * Helper function to make code more readable. It handles all drag and drop
+ * operations of the existing favorites items on the favorites bar.
+ */
+ void handleExistingFavoriteDragAndDrop(S32 x, S32 y);
+
+ /*
+ * Helper function to make code more readable. It handles all drag and drop
+ * operations of the new landmark to the favorites bar.
+ */
+ void handleNewFavoriteDragAndDrop(LLInventoryItem *item, const LLUUID& favorites_id, S32 x, S32 y);
+
+ // finds a control under the specified LOCAL point
+ LLUICtrl* findChildByLocalCoords(S32 x, S32 y);
+
+ // checks if the current order of the favorites items must be saved
+ BOOL needToSaveItemsOrder(const LLInventoryModel::item_array_t& items);
+
+ /**
+ * inserts an item identified by insertedItemId BEFORE an item identified by beforeItemId.
+ * this function assumes that an item identified by insertedItemId doesn't exist in items array.
+ */
+ void insertItem(LLInventoryModel::item_array_t& items, const LLUUID& dest_item_id, LLViewerInventoryItem* insertedItem, bool insert_before);
+
+ // finds an item by it's UUID in the items array
+ LLInventoryModel::item_array_t::iterator findItemByUUID(LLInventoryModel::item_array_t& items, const LLUUID& id);
+
+ void createOverflowMenu();
+
+ void updateMenuItems(LLMenuGL* menu);
+
+ // Fits menu item label width with favorites menu width
+ void fitLabelWidth(LLMenuItemCallGL* menu_item);
+
+ void addOpenLandmarksMenuItem(LLMenuGL* menu);
+
+ void positionAndShowMenu(LLMenuGL* menu);
+
+ BOOL mShowDragMarker;
+ LLUICtrl* mLandingTab;
+ LLUICtrl* mLastTab;
+ LLTextBox* mMoreTextBox;
+ LLTextBox* mBarLabel;
+
+ LLUUID mDragItemId;
+ BOOL mStartDrag;
+ LLInventoryModel::item_array_t mItems;
+
+ BOOL mTabsHighlightEnabled;
+
+ boost::signals2::connection mEndDragConnection;
+};
+
+/**
+ * Class to store sorting order of favorites landmarks in a local file. EXT-3985.
+ * It replaced previously implemented solution to store sort index in landmark's name as a "@" prefix.
+ * Data are stored in user home directory.
+ */
+class LLFavoritesOrderStorage : public LLSingleton
+ , public LLDestroyClass
+{
+ friend class LLSingleton;
+ LLFavoritesOrderStorage(); //LLSINGLETON(LLFavoritesOrderStorage);
+ ~LLFavoritesOrderStorage() { save(); }
+ LOG_CLASS(LLFavoritesOrderStorage);
+public:
+ /**
+ * Sets sort index for specified with LLUUID favorite landmark
+ */
+ void setSortIndex(const LLViewerInventoryItem* inv_item, S32 sort_index);
+
+ /**
+ * Gets sort index for specified with LLUUID favorite landmark
+ */
+ S32 getSortIndex(const LLUUID& inv_item_id);
+ void removeSortIndex(const LLUUID& inv_item_id);
+
+ void getSLURL(const LLUUID& asset_id);
+
+ // Saves current order of the passed items using inventory item sort field.
+ // Resets 'items' sort fields and saves them on server.
+ // Is used to save order for Favorites folder.
+ void saveItemsOrder(const LLInventoryModel::item_array_t& items);
+
+ void saveOrder();
+
+ void rearrangeFavoriteLandmarks(const LLUUID& source_item_id, const LLUUID& target_item_id);
+
+ /**
+ * Implementation of LLDestroyClass. Calls cleanup() instance method.
+ *
+ * It is important this callback is called before gInventory is cleaned.
+ * For now it is called from LLAppViewer::cleanup() -> LLAppViewer::disconnectViewer(),
+ * Inventory is cleaned later from LLAppViewer::cleanup() after LLAppViewer::disconnectViewer() is called.
+ * @see cleanup()
+ */
+ static void destroyClass();
+
+ const static S32 NO_INDEX;
+private:
+ /**
+ * Removes sort indexes for items which are not in Favorites bar for now.
+ */
+ void cleanup();
+
+ const static std::string SORTING_DATA_FILE_NAME;
+ std::string getSavedOrderFileName();
+ static std::string getStoredFavoritesFilename();
+
+ void load();
+ void save();
+
+ void saveFavoritesSLURLs();
+
+ // Remove record of current user's favorites from file on disk.
+ void removeFavoritesRecordOfUser();
+
+ void onLandmarkLoaded(const LLUUID& asset_id, class LLLandmark* landmark);
+ void storeFavoriteSLURL(const LLUUID& asset_id, std::string& slurl);
+
+ typedef std::map sort_index_map_t;
+ sort_index_map_t mSortIndexes;
+
+ typedef std::map slurls_map_t;
+ slurls_map_t mSLURLs;
+ std::set mMissingSLURLs;
+ bool mIsDirty;
+
+ struct IsNotInFavorites
+ {
+ IsNotInFavorites(const LLInventoryModel::item_array_t& items)
+ : mFavoriteItems(items)
+ {
+
+ }
+
+ /**
+ * Returns true if specified item is not found among inventory items
+ */
+ bool operator()(const sort_index_map_t::value_type& id_index_pair) const
+ {
+ LLPointer item = gInventory.getItem(id_index_pair.first);
+ if (item.isNull()) return true;
+
+ LLInventoryModel::item_array_t::const_iterator found_it =
+ std::find(mFavoriteItems.begin(), mFavoriteItems.end(), item);
+
+ return found_it == mFavoriteItems.end();
+ }
+ private:
+ LLInventoryModel::item_array_t mFavoriteItems;
+ };
+
+};
+
+inline
+LLFavoritesOrderStorage::LLFavoritesOrderStorage() :
+ mIsDirty(false)
+{ load(); }
+
+#endif // LL_LLFAVORITESBARCTRL_H
diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp
index 42f46fb2e..096df5cde 100644
--- a/indra/newview/llfeaturemanager.cpp
+++ b/indra/newview/llfeaturemanager.cpp
@@ -421,6 +421,9 @@ void LLFeatureManager::parseGPUTable(std::string filename)
else
{
LL_WARNS("RenderInit") << "GPU '" << rawRenderer << "' not recognized" << LL_ENDL;
+ mGPUString = rawRenderer;
+ mGPUClass = EGPUClass::GPU_CLASS_3;
+ mGPUSupported = true;
}
}
diff --git a/indra/newview/llfloaterabout.cpp b/indra/newview/llfloaterabout.cpp
index 48bf7a836..7c991e4d4 100644
--- a/indra/newview/llfloaterabout.cpp
+++ b/indra/newview/llfloaterabout.cpp
@@ -144,7 +144,7 @@ LLFloaterAbout::LLFloaterAbout()
__DATE__, __TIME__,
LLVersionInfo::getChannel().c_str()));
support_widget->appendColoredText(version, FALSE, FALSE, gColors.getColor("TextFgReadOnlyColor"));
- support_widget->appendStyledText(LLTrans::getString("ReleaseNotes"), false, false, viewer_link_style);
+ support_widget->appendText(LLTrans::getString("ReleaseNotes"), false, false, viewer_link_style);
std::string support;
support.append("\n\n");
@@ -209,7 +209,7 @@ LLFloaterAbout::LLFloaterAbout()
{
LLStyleSP server_link_style(new LLStyle(*viewer_link_style));
server_link_style->setLinkHREF(url);
- support_widget->appendStyledText(LLTrans::getString("ReleaseNotes"), false, false, server_link_style);
+ support_widget->appendText(LLTrans::getString("ReleaseNotes"), false, false, server_link_style);
}
support = "\n\n";
diff --git a/indra/newview/llfloateravatarlist.cpp b/indra/newview/llfloateravatarlist.cpp
index 7c67b9a3d..cbd8d9e92 100644
--- a/indra/newview/llfloateravatarlist.cpp
+++ b/indra/newview/llfloateravatarlist.cpp
@@ -70,7 +70,7 @@ const S32& radar_namesystem()
namespace
{
- void chat_avatar_status(const std::string& name, const LLUUID& key, ERadarStatType type, bool entering, const F32& dist)
+ void chat_avatar_status(const std::string& name, const LLUUID& key, ERadarStatType type, bool entering, const F32& dist, bool flood = false)
{
static LLCachedControl radar_chat_alerts(gSavedSettings, "RadarChatAlerts");
if (!radar_chat_alerts) return;
@@ -82,6 +82,8 @@ namespace
}
//
if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMETAGS)) return; // RLVa:LF Don't announce people are around when blind, that cheats the system.
+ static LLCachedControl radar_alert_flood(gSavedSettings, "RadarAlertFlood");
+ if (flood && !radar_alert_flood) return;
static LLCachedControl radar_alert_sim(gSavedSettings, "RadarAlertSim");
static LLCachedControl radar_alert_draw(gSavedSettings, "RadarAlertDraw");
static LLCachedControl radar_alert_shout_range(gSavedSettings, "RadarAlertShoutRange");
@@ -96,11 +98,11 @@ namespace
case STAT_TYPE_DRAW: if (radar_alert_draw) args["[RANGE]"] = LLTrans::getString("draw_distance"); break;
case STAT_TYPE_SHOUTRANGE: if (radar_alert_shout_range) args["[RANGE]"] = LLTrans::getString("shout_range"); break;
case STAT_TYPE_CHATRANGE: if (radar_alert_chat_range) args["[RANGE]"] = LLTrans::getString("chat_range"); break;
- case STAT_TYPE_AGE: if (radar_alert_age) chat.mText = name + " " + LLTrans::getString("has_triggered_your_avatar_age_alert") + "."; break;
+ case STAT_TYPE_AGE: if (radar_alert_age) chat.mText = name + ' ' + LLTrans::getString("has_triggered_your_avatar_age_alert") + '.'; break;
default: llassert(type); break;
}
args["[NAME]"] = name;
- args["[ACTION]"] = LLTrans::getString(entering ? "has_entered" : "has_left");
+ args["[ACTION]"] = LLTrans::getString((entering ? "has_entered" : "has_left") + (flood ? "_flood" : LLStringUtil::null));
if (args.find("[RANGE]") != args.end())
chat.mText = LLTrans::getString("radar_alert_template", args);
else if (chat.mText.empty()) return;
@@ -110,6 +112,7 @@ namespace
if (radar_show_dist) chat.mText += llformat(" (%.2fm)", dist);
}
chat.mFromName = name;
+ chat.mFromID = key;
if (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) // RLVa:LF - No way!
chat.mURL = llformat("secondlife:///app/agent/%s/about", key.asString().c_str());
chat.mSourceType = CHAT_SOURCE_SYSTEM;
@@ -140,62 +143,75 @@ LLAvatarListEntry::LLAvatarListEntry(const LLUUID& id, const std::string& name,
LLAvatarPropertiesProcessor& inst(LLAvatarPropertiesProcessor::instance());
inst.addObserver(mID, this);
inst.sendAvatarPropertiesRequest(mID);
+ inst.sendAvatarNotesRequest(mID);
}
LLAvatarListEntry::~LLAvatarListEntry()
{
- setPosition(mPosition, F32_MIN, false); // Dead and gone
+ static LLCachedControl radar_alert_flood_leaving(gSavedSettings, "RadarAlertFloodLeaving");
+ bool cleanup = LLFloaterAvatarList::isCleanup();
+ if (radar_alert_flood_leaving || !cleanup)
+ {
+ setPosition(mPosition, F32_MIN, false, cleanup); // Dead and gone
+ }
LLAvatarPropertiesProcessor::instance().removeObserver(mID, this);
}
// virtual
void LLAvatarListEntry::processProperties(void* data, EAvatarProcessorType type)
{
- if (type == APT_PROPERTIES)
+ // If one wanted more information that gets displayed on profiles to be displayed, here would be the place to do it.
+ switch(type)
{
- LLAvatarPropertiesProcessor& inst(LLAvatarPropertiesProcessor::instance());
- inst.removeObserver(mID, this);
- const LLAvatarData* pAvatarData = static_cast(data);
- if (pAvatarData && (pAvatarData->avatar_id != LLUUID::null))
- {
- using namespace boost::gregorian;
- int year, month, day;
- sscanf(pAvatarData->born_on.c_str(),"%d/%d/%d",&month,&day,&year);
- try
+ case APT_PROPERTIES:
+ if (mAge == -1)
{
- mAge = (day_clock::local_day() - date(year, month, day)).days();
- }
- catch(const std::exception&)
- {
- LL_WARNS() << "Failed to extract age from APT_PROPERTIES for " << mID << ", received \"" << pAvatarData->born_on << "\". Requesting properties again." << LL_ENDL;
- inst.addObserver(mID, this);
- inst.sendAvatarPropertiesRequest(mID);
- return;
- }
- if (!mStats[STAT_TYPE_AGE] && mAge >= 0) //Only announce age once per entry.
- {
- static const LLCachedControl sAvatarAgeAlertDays(gSavedSettings, "AvatarAgeAlertDays");
- if ((U32)mAge < sAvatarAgeAlertDays)
+ LLAvatarPropertiesProcessor& inst(LLAvatarPropertiesProcessor::instance());
+ const LLAvatarData* pAvatarData = static_cast(data);
+ if (pAvatarData && (pAvatarData->avatar_id.notNull()))
{
- chat_avatar_status(mName, mID, STAT_TYPE_AGE, mStats[STAT_TYPE_AGE] = true, (mPosition - gAgent.getPositionGlobal()).magVec());
+ using namespace boost::gregorian;
+ int year, month, day;
+ if (sscanf(pAvatarData->born_on.c_str(),"%d/%d/%d",&month,&day,&year) == 3)
+ try
+ {
+ mAge = (day_clock::local_day() - date(year, month, day)).days();
+ }
+ catch(const std::out_of_range&) {} // date throws this, so we didn't assign
+
+ if (mAge >= 0)
+ {
+ static const LLCachedControl sAvatarAgeAlertDays(gSavedSettings, "AvatarAgeAlertDays");
+ if (!mStats[STAT_TYPE_AGE] && (U32)mAge < sAvatarAgeAlertDays) //Only announce age once per entry.
+ chat_avatar_status(mName, mID, STAT_TYPE_AGE, mStats[STAT_TYPE_AGE] = true, (mPosition - gAgent.getPositionGlobal()).magVec());
+ }
+ 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;
+ inst.sendAvatarPropertiesRequest(mID);
+ }
}
}
- // If one wanted more information that gets displayed on profiles to be displayed, here would be the place to do it.
- }
+ break;
+ case APT_NOTES:
+ if (const LLAvatarNotes* pAvatarNotes = static_cast(data))
+ mNotes = !pAvatarNotes->notes.empty();
+ break;
+ default: break;
}
}
-void LLAvatarListEntry::setPosition(const LLVector3d& position, const F32& dist, bool drawn)
+void LLAvatarListEntry::setPosition(const LLVector3d& position, const F32& dist, bool drawn, bool flood)
{
mPosition = position;
bool here(dist != F32_MIN); // F32_MIN only if dead
bool this_sim(here && (gAgent.getRegion()->pointInRegionGlobal(position) || !(LLWorld::getInstance()->positionRegionValidGlobal(position))));
- if (this_sim != mStats[STAT_TYPE_SIM]) chat_avatar_status(mName, mID, STAT_TYPE_SIM, mStats[STAT_TYPE_SIM] = this_sim, dist);
- if (drawn != mStats[STAT_TYPE_DRAW]) chat_avatar_status(mName, mID, STAT_TYPE_DRAW, mStats[STAT_TYPE_DRAW] = drawn, dist);
+ if (this_sim != mStats[STAT_TYPE_SIM]) chat_avatar_status(mName, mID, STAT_TYPE_SIM, mStats[STAT_TYPE_SIM] = this_sim, dist, flood);
+ if (drawn != mStats[STAT_TYPE_DRAW]) chat_avatar_status(mName, mID, STAT_TYPE_DRAW, mStats[STAT_TYPE_DRAW] = drawn, dist, flood);
bool shoutrange(here && dist < LFSimFeatureHandler::getInstance()->shoutRange());
- if (shoutrange != mStats[STAT_TYPE_SHOUTRANGE]) chat_avatar_status(mName, mID, STAT_TYPE_SHOUTRANGE, mStats[STAT_TYPE_SHOUTRANGE] = shoutrange, dist);
+ if (shoutrange != mStats[STAT_TYPE_SHOUTRANGE]) chat_avatar_status(mName, mID, STAT_TYPE_SHOUTRANGE, mStats[STAT_TYPE_SHOUTRANGE] = shoutrange, dist, flood);
bool chatrange(here && dist < LFSimFeatureHandler::getInstance()->sayRange());
- if (chatrange != mStats[STAT_TYPE_CHATRANGE]) chat_avatar_status(mName, mID, STAT_TYPE_CHATRANGE, mStats[STAT_TYPE_CHATRANGE] = chatrange, dist);
+ if (chatrange != mStats[STAT_TYPE_CHATRANGE]) chat_avatar_status(mName, mID, STAT_TYPE_CHATRANGE, mStats[STAT_TYPE_CHATRANGE] = chatrange, dist, flood);
}
void LLAvatarListEntry::resetName(const bool& hide_tags, const bool& anon_names, const std::string& hidden)
@@ -240,6 +256,8 @@ LLFloaterAvatarList::LLFloaterAvatarList() : LLFloater(std::string("radar")),
LLFloaterAvatarList::~LLFloaterAvatarList()
{
+ mCleanup = true;
+ mAvatars.clear();
}
//static
@@ -315,7 +333,7 @@ namespace
{
bool handleEvent(LLPointer event, const LLSD& userdata)
{
- LLFloaterAvatarList::instance().setFocusAvatar(get_focused_list_id_selected());
+ LLFloaterAvatarList::setFocusAvatar(get_focused_list_id_selected());
return true;
}
};
@@ -401,6 +419,7 @@ BOOL LLFloaterAvatarList::postBuild()
gSavedSettings.getControl("RadarColumnAltitudeHidden")->getSignal()->connect(boost::bind(&LLFloaterAvatarList::assessColumns, this));
gSavedSettings.getControl("RadarColumnActivityHidden")->getSignal()->connect(boost::bind(&LLFloaterAvatarList::assessColumns, this));
gSavedSettings.getControl("RadarColumnVoiceHidden")->getSignal()->connect(boost::bind(&LLFloaterAvatarList::assessColumns, this));
+ gSavedSettings.getControl("RadarColumnNotesHidden")->getSignal()->connect(boost::bind(&LLFloaterAvatarList::assessColumns, this));
gSavedSettings.getControl("RadarColumnAgeHidden")->getSignal()->connect(boost::bind(&LLFloaterAvatarList::assessColumns, this));
gSavedSettings.getControl("RadarColumnTimeHidden")->getSignal()->connect(boost::bind(&LLFloaterAvatarList::assessColumns, this));
@@ -413,7 +432,7 @@ BOOL LLFloaterAvatarList::postBuild()
mAvatarList->setSortChangedCallback(boost::bind(&LLFloaterAvatarList::onAvatarSortingChanged,this));
for (LLViewerRegion* region : LLWorld::instance().getRegionList())
{
- updateAvatarList(region);
+ updateAvatarList(region, true);
}
assessColumns();
@@ -445,6 +464,21 @@ void col_helper(const bool hide, LLCachedControl &setting, LLScrollListColu
}
}
+enum AVATARS_COLUMN_ORDER
+{
+ LIST_MARK,
+ LIST_AVATAR_NAME,
+ LIST_DISTANCE,
+ LIST_POSITION,
+ LIST_ALTITUDE,
+ LIST_ACTIVITY,
+ LIST_VOICE,
+ LIST_NOTES,
+ LIST_AGE,
+ LIST_TIME,
+ LIST_CLIENT,
+};
+
//Macro to reduce redundant lines. Preprocessor concatenation and stringizing avoids bloat that
//wrapping in a class would create.
#define BIND_COLUMN_TO_SETTINGS(col, name)\
@@ -459,6 +493,7 @@ void LLFloaterAvatarList::assessColumns()
BIND_COLUMN_TO_SETTINGS(LIST_ALTITUDE,Altitude);
BIND_COLUMN_TO_SETTINGS(LIST_ACTIVITY,Activity);
BIND_COLUMN_TO_SETTINGS(LIST_VOICE,Voice);
+ BIND_COLUMN_TO_SETTINGS(LIST_NOTES,Notes);
BIND_COLUMN_TO_SETTINGS(LIST_AGE,Age);
BIND_COLUMN_TO_SETTINGS(LIST_TIME,Time);
@@ -515,7 +550,7 @@ const F32& radar_range_radius()
return radius;
}
-void LLFloaterAvatarList::updateAvatarList(const LLViewerRegion* region)
+void LLFloaterAvatarList::updateAvatarList(const LLViewerRegion* region, bool first)
{
// Check whether updates are enabled
if (!mUpdate)
@@ -561,7 +596,7 @@ void LLFloaterAvatarList::updateAvatarList(const LLViewerRegion* region)
}
// Announce position
- entry->setPosition(position, (position - mypos).magVec(), avatarp);
+ entry->setPosition(position, (position - mypos).magVec(), avatarp, first);
// Mark as typing if they are typing
if (avatarp && avatarp->isTyping()) entry->setActivity(LLAvatarListEntry::ACTIVITY_TYPING);
@@ -582,13 +617,13 @@ void LLFloaterAvatarList::updateAvatarList(const LLViewerRegion* region)
U32 num_ids = 0;
while(!announce_keys.empty())
{
- ids << "," << announce_keys.front().asString();
+ ids << ',' << announce_keys.front().asString();
++num_ids;
if (ids.tellp() > 200)
{
send_keys_message(transact_num, num_ids, ids.str());
ids.seekp(num_ids = 0);
- ids.str("");
+ ids.str(LLStringUtil::null);
}
announce_keys.pop();
}
@@ -903,6 +938,12 @@ void LLFloaterAvatarList::refreshAvatarList()
element.columns.add(voice);
}
+ static const LLCachedControl hide_notes("RadarColumnNotesHidden");
+ if (!hide_notes)
+ {
+ element.columns.add(LLScrollListCell::Params().column("notes").type("checkbox").enabled(false).value(entry->mNotes));
+ }
+
static const LLCachedControl hide_age("RadarColumnAgeHidden");
if (!hide_age)
{
@@ -1092,7 +1133,6 @@ void LLFloaterAvatarList::trackAvatar(const LLAvatarListEntry* entry) const
LLAvatarListEntry* LLFloaterAvatarList::getAvatarEntry(const LLUUID& avatar) const
{
- if (avatar.isNull()) return NULL;
av_list_t::const_iterator iter = std::find_if(mAvatars.begin(),mAvatars.end(),LLAvatarListEntry::uuidMatch(avatar));
return (iter != mAvatars.end()) ? iter->get() : NULL;
}
@@ -1149,9 +1189,16 @@ void LLFloaterAvatarList::removeFocusFromAll()
}
}
+// static
void LLFloaterAvatarList::setFocusAvatar(const LLUUID& id)
{
if (!gAgentCamera.lookAtObject(id, false) && !lookAtAvatar(id)) return;
+ if (auto inst = getIfExists())
+ inst->setFocusAvatarInternal(id);
+}
+
+void LLFloaterAvatarList::setFocusAvatarInternal(const LLUUID& id)
+{
av_list_t::iterator iter = std::find_if(mAvatars.begin(),mAvatars.end(),LLAvatarListEntry::uuidMatch(id));
if (iter == mAvatars.end()) return;
removeFocusFromAll();
@@ -1255,13 +1302,13 @@ void LLFloaterAvatarList::sendKeys() const
for (U32 i = 0; i < regionp->mMapAvatarIDs.size(); ++i)
{
- ids << "," << regionp->mMapAvatarIDs.at(i);
+ ids << ',' << regionp->mMapAvatarIDs.at(i);
++num_ids;
if (ids.tellp() > 200)
{
send_keys_message(transact_num, num_ids, ids.str());
ids.seekp(num_ids = 0);
- ids.str("");
+ ids.str(LLStringUtil::null);
}
}
if (num_ids > 0) send_keys_message(transact_num, num_ids, ids.str());
@@ -1400,7 +1447,7 @@ std::string LLFloaterAvatarList::getSelectedNames(const std::string& separator)
std::string LLFloaterAvatarList::getSelectedName() const
{
LLAvatarListEntry* entry = getAvatarEntry(getSelectedID());
- return entry ? entry->getName() : "";
+ return entry ? entry->getName() : LLStringUtil::null;
}
LLUUID LLFloaterAvatarList::getSelectedID() const
diff --git a/indra/newview/llfloateravatarlist.h b/indra/newview/llfloateravatarlist.h
index 93230f9a5..233eb4618 100644
--- a/indra/newview/llfloateravatarlist.h
+++ b/indra/newview/llfloateravatarlist.h
@@ -79,7 +79,7 @@ enum ACTIVITY_TYPE
* Update world position.
* Affects age.
*/
- void setPosition(const LLVector3d& position, const F32& dist, bool drawn);
+ void setPosition(const LLVector3d& position, const F32& dist, bool drawn, bool flood = false);
const LLVector3d& getPosition() const { return mPosition; }
@@ -143,6 +143,7 @@ private:
bool mMarked;
bool mFocused;
bool mIsInList;
+ bool mNotes = false;
int mAge;
/**
@@ -202,7 +203,7 @@ public:
/**
* @brief Updates the internal avatar list with the currently present avatars.
*/
- void updateAvatarList(const class LLViewerRegion* region);
+ void updateAvatarList(const class LLViewerRegion* region, bool first = false);
/**
* @brief Refresh avatar list (display)
@@ -239,20 +240,6 @@ public:
// when a line editor loses keyboard focus, it is committed.
// commit callbacks are named onCommitWidgetName by convention.
//void onCommitBaz(LLUICtrl* ctrl, void *userdata);
-
- enum AVATARS_COLUMN_ORDER
- {
- LIST_MARK,
- LIST_AVATAR_NAME,
- LIST_DISTANCE,
- LIST_POSITION,
- LIST_ALTITUDE,
- LIST_ACTIVITY,
- LIST_VOICE,
- LIST_AGE,
- LIST_TIME,
- LIST_CLIENT,
- };
typedef boost::function avlist_command_t;
@@ -264,7 +251,7 @@ public:
/**
* @brief Focus camera on specified avatar
*/
- void setFocusAvatar(const LLUUID& id);
+ static void setFocusAvatar(const LLUUID& id);
/**
* @brief Focus camera on previous avatar
@@ -318,8 +305,6 @@ public:
static bool onConfirmRadarChatKeys(const LLSD& notification, const LLSD& response );
- static void callbackIdle(void *userdata);
-
void doCommand(avlist_command_t cmd, bool single = false) const;
/**
@@ -330,14 +315,22 @@ public:
*/
void expireAvatarList(const std::list& ids);
void updateAvatarSorting();
+ static bool isCleanup()
+ {
+ const auto& inst = getIfExists();
+ return inst && inst->mCleanup;
+ }
private:
+ void setFocusAvatarInternal(const LLUUID& id);
+
/**
* @brief Pointer to the avatar scroll list
*/
LLScrollListCtrl* mAvatarList;
av_list_t mAvatars;
bool mDirtyAvatarSorting;
+ bool mCleanup = false;
/**
* @brief true when Updating
diff --git a/indra/newview/llfloaterchat.cpp b/indra/newview/llfloaterchat.cpp
index 95c683582..b0607210f 100644
--- a/indra/newview/llfloaterchat.cpp
+++ b/indra/newview/llfloaterchat.cpp
@@ -45,6 +45,7 @@
#include "llcombobox.h"
#include "lltextparser.h"
#include "lltrans.h"
+#include "llurlregistry.h"
#include "llwindow.h"
// project include
@@ -94,7 +95,6 @@ LLFloaterChat::LLFloaterChat(const LLSD& seed)
LLTextEditor* history_editor_with_mute = getChild("Chat History Editor with mute");
getChild("show mutes")->setCommitCallback(boost::bind(&LLFloaterChat::onClickToggleShowMute, this, _2, getChild("Chat History Editor"), history_editor_with_mute));
- history_editor_with_mute->setVisible(false);
getChild("chat_history_open")->setCommitCallback(boost::bind(show_log_browser, "chat", "chat"));
}
@@ -201,7 +201,7 @@ void add_timestamped_line(LLViewerTextEditor* edit, LLChat chat, const LLColor4&
if (chat.mSourceType == CHAT_SOURCE_OBJECT)
{
LLStringUtil::trim(chat.mFromName);
- if (!chat.mFromName.length())
+ if (chat.mFromName.empty())
{
chat.mFromName = LLTrans::getString("Unnamed");
line = chat.mFromName + line;
@@ -212,19 +212,19 @@ void add_timestamped_line(LLViewerTextEditor* edit, LLChat chat, const LLColor4&
bool is_irc = italicize && chat.mChatStyle == CHAT_STYLE_IRC;
// If the chat line has an associated url, link it up to the name.
if (!chat.mURL.empty()
- && (line.length() > chat.mFromName.length() && line.find(chat.mFromName,0) == 0))
+ && boost::algorithm::starts_with(line, chat.mFromName))
{
- std::string start_line = line.substr(0, chat.mFromName.length() + 1);
- line = line.substr(chat.mFromName.length() + 1);
+ line = line.substr(chat.mFromName.length());
LLStyleSP sourceStyle = LLStyleMap::instance().lookup(chat.mFromID, chat.mURL);
sourceStyle->mItalic = is_irc;
- edit->appendStyledText(start_line, false, prepend_newline, sourceStyle);
+ edit->appendText(chat.mFromName, false, prepend_newline, sourceStyle, false);
prepend_newline = false;
}
LLStyleSP style(new LLStyle);
style->setColor(color);
style->mItalic = is_irc;
- edit->appendStyledText(line, false, prepend_newline, style);
+ style->mBold = chat.mChatType == CHAT_TYPE_SHOUT;
+ edit->appendText(line, false, prepend_newline, style, false);
}
void log_chat_text(const LLChat& chat)
@@ -339,8 +339,6 @@ void LLFloaterChat::setHistoryCursorAndScrollToEnd()
//static
void LLFloaterChat::onClickToggleShowMute(bool show_mute, LLTextEditor* history_editor, LLTextEditor* history_editor_with_mute)
{
- history_editor->setVisible(!show_mute);
- history_editor_with_mute->setVisible(show_mute);
(show_mute ? history_editor_with_mute : history_editor)->setCursorAndScrollToEnd();
}
@@ -387,7 +385,19 @@ void LLFloaterChat::addChat(const LLChat& chat,
// We display anything if it's not an IM. If it's an IM, check pref...
if ( !from_instant_message || gSavedSettings.getBOOL("IMInChatConsole") )
{
- gConsole->addConsoleLine(chat.mText, text_color);
+ // Replace registered urls in the console so it looks right.
+ std::string chit(chat.mText), // Read through this
+ chat; // Add parts to this
+ LLUrlMatch match;
+ while (!chit.empty() && LLUrlRegistry::instance().findUrl(chit, match))
+ {
+ const auto start(match.getStart()), length(match.getEnd()+1-start);
+ if (start > 0) chat += chit.substr(0, start); // Add up to the start of the match
+ chat += match.getLabel() + match.getQuery(); // Add the label and the query
+ chit.erase(0, start+length); // remove the url match and all before it
+ }
+ if (!chit.empty()) chat += chit; // Add any leftovers
+ gConsole->addConsoleLine(chat, text_color);
}
}
diff --git a/indra/newview/llfloatercustomize.cpp b/indra/newview/llfloatercustomize.cpp
index 657920701..63aa904dd 100644
--- a/indra/newview/llfloatercustomize.cpp
+++ b/indra/newview/llfloatercustomize.cpp
@@ -55,8 +55,7 @@
#include "statemachine/aifilepicker.h"
#include "hippogridmanager.h"
-//#include "aixmllindengenepool.h"
-#include "aifile.h"
+#include "aixmllindengenepool.h"
using namespace LLAvatarAppearanceDefines;
@@ -119,9 +118,9 @@ LLFloaterCustomize::LLFloaterCustomize()
gInventory.addObserver(mInventoryObserver);
LLOutfitObserver& outfit_observer = LLOutfitObserver::instance();
- outfit_observer.addBOFReplacedCallback(boost::bind(&LLFloaterCustomize::refreshCurrentOutfitName, this, ""));
- outfit_observer.addBOFChangedCallback(boost::bind(&LLFloaterCustomize::refreshCurrentOutfitName, this, ""));
- outfit_observer.addCOFChangedCallback(boost::bind(&LLFloaterCustomize::refreshCurrentOutfitName, this, ""));
+ outfit_observer.addBOFReplacedCallback(boost::bind(&LLFloaterCustomize::refreshCurrentOutfitName, this, LLStringUtil::null));
+ outfit_observer.addBOFChangedCallback(boost::bind(&LLFloaterCustomize::refreshCurrentOutfitName, this, LLStringUtil::null));
+ outfit_observer.addCOFChangedCallback(boost::bind(&LLFloaterCustomize::refreshCurrentOutfitName, this, LLStringUtil::null));
LLCallbackMap::map_t factory_map;
const std::string &invalid_name = LLWearableType::getTypeName(LLWearableType::WT_INVALID);
@@ -238,7 +237,11 @@ void LLFloaterCustomize::editWearable(LLViewerWearable* wearable, bool disable_c
{
if(!wearable)
return;
- LLFloaterCustomize::getInstance()->setCurrentWearableType(wearable->getType(), disable_camera_switch);
+ auto& inst = LLFloaterCustomize::instance();
+ inst.setCurrentWearableType(wearable->getType(), disable_camera_switch);
+ U32 index(0);
+ gAgentWearables.getWearableIndex(wearable, index);
+ static_cast(inst.mTabContainer->getCurrentPanel())->setWearableIndex(index);
}
//static
@@ -314,7 +317,6 @@ void LLFloaterCustomize::onBtnImport()
void LLFloaterCustomize::onBtnImport_continued(AIFilePicker* filepicker)
{
-#if 0
if (!filepicker->hasFilename())
{
// User canceled import.
@@ -457,7 +459,6 @@ void LLFloaterCustomize::onBtnImport_continued(AIFilePicker* filepicker)
{
AIAlert::add("AIXMLImportWearableTypeMismatch", args("[TYPE]", label)("[ARCHETYPENAME]", wearable_types));
}
-#endif
}
// reX: new function
@@ -502,7 +503,6 @@ void LLFloaterCustomize::onBtnExport()
//static
void LLFloaterCustomize::onBtnExport_continued(LLViewerWearable* edit_wearable, AIFilePicker* filepicker)
{
-#if 0
if (!filepicker->hasFilename())
{
// User canceled export.
@@ -514,9 +514,7 @@ void LLFloaterCustomize::onBtnExport_continued(LLViewerWearable* edit_wearable,
bool success = false;
try
{
- AIFile outfile(filename, "wb");
-
- AIXMLLindenGenepool linden_genepool(outfile);
+ AIXMLLindenGenepool linden_genepool(filename);
linden_genepool.child(edit_wearable->getArchetype());
success = true;
@@ -530,7 +528,6 @@ void LLFloaterCustomize::onBtnExport_continued(LLViewerWearable* edit_wearable,
{
AIAlert::add_modal("AIXMLExportSuccess", AIArgs("[FILE]", filename));
}
-#endif
}
void LLFloaterCustomize::onBtnOk()
@@ -677,7 +674,8 @@ const S32 HEADER_HEIGHT = 3 * (LINE_HEIGHT + LLFLOATER_VPAD) + (2 * LLPANEL_BORD
void LLFloaterCustomize::wearablesChanged(LLWearableType::EType type)
{
llassert( type < LLWearableType::WT_COUNT );
- gSavedSettings.setU32("AvatarSex", (gAgentAvatarp->getSex() == SEX_MALE) );
+ if (type == LLWearableType::WT_SHAPE)
+ gSavedSettings.setU32("AvatarSex", (gAgentAvatarp->getSex() == SEX_MALE));
LLPanelEditWearable* panel = mWearablePanelList[ type ];
if( panel )
diff --git a/indra/newview/llfloatergodtools.cpp b/indra/newview/llfloatergodtools.cpp
index b024b0eee..7e5861276 100644
--- a/indra/newview/llfloatergodtools.cpp
+++ b/indra/newview/llfloatergodtools.cpp
@@ -556,7 +556,7 @@ void LLPanelRegionTools::onSaveState(void* userdata)
gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
gMessageSystem->nextBlockFast(_PREHASH_DataBlock);
- gMessageSystem->addStringFast(_PREHASH_Filename, NULL);
+ gMessageSystem->addStringFast(_PREHASH_Filename, nullptr);
gAgent.sendReliableMessage();
}
}
@@ -1354,7 +1354,7 @@ void LLPanelRequestTools::onClickRequest()
if(dest == SELECTION)
{
std::string req =getChild("request")->getValue();
- req = req.substr(0, req.find_first_of(" "));
+ req = req.substr(0, req.find_first_of(' '));
std::string param = getChild("parameter")->getValue();
LLSelectMgr::getInstance()->sendGodlikeRequest(req, param);
}
@@ -1401,11 +1401,11 @@ void LLPanelRequestTools::sendRequest(const LLHost& host)
host,
FALSE,
terrain_download_done,
- NULL);
+ nullptr);
}
else
{
- req = req.substr(0, req.find_first_of(" "));
+ req = req.substr(0, req.find_first_of(' '));
sendRequest(req, getChild("parameter")->getValue().asString(), host);
}
}
diff --git a/indra/newview/llfloaterlandmark.cpp b/indra/newview/llfloaterlandmark.cpp
index 00d7cd86c..d94546a08 100644
--- a/indra/newview/llfloaterlandmark.cpp
+++ b/indra/newview/llfloaterlandmark.cpp
@@ -104,7 +104,7 @@ BOOL LLFloaterLandmark::postBuild()
mInventoryPanel->setAllowMultiSelect(FALSE);
// store this filter as the default one
- mInventoryPanel->getRootFolder()->getFilter()->markDefault();
+ mInventoryPanel->getRootFolder()->getFilter().markDefault();
// Commented out to stop opening all folders with textures
mInventoryPanel->openDefaultFolderForType(LLAssetType::AT_LANDMARK);
diff --git a/indra/newview/llfloatermarketplacelistings.cpp b/indra/newview/llfloatermarketplacelistings.cpp
new file mode 100644
index 000000000..e51cbd6c7
--- /dev/null
+++ b/indra/newview/llfloatermarketplacelistings.cpp
@@ -0,0 +1,967 @@
+/**
+ * @file llfloatermarketplacelistings.cpp
+ * @brief Implementation of the marketplace listings floater and panels
+ * @author merov@lindenlab.com
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llfloatermarketplacelistings.h"
+
+//#include "llfloaterreg.h"
+#include "llfiltereditor.h"
+#include "llfolderview.h"
+#include "llinventorybridge.h"
+#include "llinventorymodelbackgroundfetch.h"
+#include "llinventoryobserver.h"
+#include "llinventoryfunctions.h"
+#include "llmarketplacefunctions.h"
+//#include "llnotificationhandler.h"
+//#include "llnotificationmanager.h"
+#include "llnotificationsutil.h"
+//#include "llsidepaneliteminfo.h"
+#include "lltextbox.h"
+#include "lltrans.h"
+
+///----------------------------------------------------------------------------
+/// LLPanelMarketplaceListings
+///----------------------------------------------------------------------------
+
+static LLPanelInjector t_panel_status("llpanelmarketplacelistings");
+
+LLPanelMarketplaceListings::LLPanelMarketplaceListings()
+: mRootFolder(NULL)
+, mSortOrder(LLInventoryFilter::SO_FOLDERS_BY_NAME)
+, mFilterListingFoldersOnly(false)
+{
+}
+
+LLPanelMarketplaceListings::~LLPanelMarketplaceListings() { delete mMenu; }
+
+void showMenu(LLView* button, LLMenuGL* menu)
+{
+ menu->buildDrawLabels();
+ menu->updateParent(LLMenuGL::sMenuContainer);
+ const auto& rect = button->getRect();
+ LLMenuGL::showPopup(button->getParent(), menu, rect.mLeft, rect.mBottom);
+}
+
+BOOL LLPanelMarketplaceListings::postBuild()
+{
+ childSetAction("add_btn", boost::bind(&LLPanelMarketplaceListings::onAddButtonClicked, this));
+ childSetAction("audit_btn", boost::bind(&LLPanelMarketplaceListings::onAuditButtonClicked, this));
+ mMenu = LLUICtrlFactory::instance().buildMenu("menu_marketplace_view.xml", LLMenuGL::sMenuContainer);
+ auto sort = getChild("sort_btn");
+ sort->setCommitCallback(boost::bind(showMenu, _1, mMenu));
+
+ mFilterEditor = getChild("filter_editor");
+ mFilterEditor->setCommitCallback(boost::bind(&LLPanelMarketplaceListings::onFilterEdit, this, _2));
+
+ mAuditBtn = getChild("audit_btn");
+ mAuditBtn->setEnabled(FALSE);
+
+ return LLPanel::postBuild();
+}
+
+BOOL LLPanelMarketplaceListings::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
+ EDragAndDropType cargo_type,
+ void* cargo_data,
+ EAcceptance* accept,
+ std::string& tooltip_msg)
+{
+ LLView * handled_view = childrenHandleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
+ BOOL handled = (handled_view != NULL);
+ // Special case the drop zone
+ if (handled && (handled_view->getName() == "marketplace_drop_zone"))
+ {
+ LLFolderView* root_folder = getRootFolder();
+ handled = root_folder->handleDragAndDropToThisFolder(mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
+ }
+ return handled;
+}
+
+void LLPanelMarketplaceListings::buildAllPanels()
+{
+ // Build the All panel first
+ LLInventoryPanel* panel_all_items;
+ panel_all_items = buildInventoryPanel("All Items", "panel_marketplace_listings_inventory.xml");
+ panel_all_items->getFilter().setEmptyLookupMessage("MarketplaceNoMatchingItems");
+ panel_all_items->getFilter().markDefault();
+
+ // Build the other panels
+ LLInventoryPanel* panel;
+ panel = buildInventoryPanel("Active Items", "panel_marketplace_listings_listed.xml");
+ panel->getFilter().setFilterMarketplaceActiveFolders();
+ panel->getFilter().setEmptyLookupMessage("MarketplaceNoMatchingItems");
+ panel->getFilter().markDefault();
+ panel = buildInventoryPanel("Inactive Items", "panel_marketplace_listings_unlisted.xml");
+ panel->getFilter().setFilterMarketplaceInactiveFolders();
+ panel->getFilter().setEmptyLookupMessage("MarketplaceNoMatchingItems");
+ panel->getFilter().markDefault();
+ panel = buildInventoryPanel("Unassociated Items", "panel_marketplace_listings_unassociated.xml");
+ panel->getFilter().setFilterMarketplaceUnassociatedFolders();
+ panel->getFilter().setEmptyLookupMessage("MarketplaceNoMatchingItems");
+ panel->getFilter().markDefault();
+
+ // Set the tab panel
+ LLTabContainer* tabs_panel = getChild("marketplace_filter_tabs");
+ tabs_panel->setCommitCallback(boost::bind(&LLPanelMarketplaceListings::onTabChange, this));
+ tabs_panel->selectTabPanel(panel_all_items); // All panel selected by default
+ mRootFolder = panel_all_items->getRootFolder(); // Keep the root of the all panel
+
+ // Set the default sort order
+ setSortOrder(gSavedSettings.getU32("MarketplaceListingsSortOrder"));
+}
+
+LLInventoryPanel* LLPanelMarketplaceListings::buildInventoryPanel(const std::string& childname, const std::string& filename)
+{
+ LLTabContainer* tabs_panel = getChild("marketplace_filter_tabs");
+ // Singu Note: These should already be built!!
+ LLInventoryPanel* panel = tabs_panel->getChild(childname, false, false);
+ llassert(panel != NULL);
+
+ // Set sort order and callbacks
+ panel->getRootFolder()->setSortOrder(LLInventoryFilter::SO_FOLDERS_BY_NAME);
+ panel->setSelectCallback(boost::bind(&LLPanelMarketplaceListings::onSelectionChange, this, panel, _1, _2));
+
+ return panel;
+}
+
+void LLPanelMarketplaceListings::setSortOrder(U32 sort_order)
+{
+ mSortOrder = sort_order;
+ gSavedSettings.setU32("MarketplaceListingsSortOrder", sort_order);
+
+ // Set each panel with that sort order
+ LLTabContainer* tabs_panel = getChild("marketplace_filter_tabs");
+ LLInventoryPanel* panel = (LLInventoryPanel*)tabs_panel->getPanelByName("All Items");
+ panel->setSortOrder(mSortOrder);
+ panel = (LLInventoryPanel*)tabs_panel->getPanelByName("Active Items");
+ panel->setSortOrder(mSortOrder);
+ panel = (LLInventoryPanel*)tabs_panel->getPanelByName("Inactive Items");
+ panel->setSortOrder(mSortOrder);
+ panel = (LLInventoryPanel*)tabs_panel->getPanelByName("Unassociated Items");
+ panel->setSortOrder(mSortOrder);
+}
+
+void LLPanelMarketplaceListings::onFilterEdit(const std::string& search_string)
+{
+ // Find active panel
+ LLInventoryPanel* panel = (LLInventoryPanel*)getChild("marketplace_filter_tabs")->getCurrentPanel();
+ if (panel)
+ {
+ // Save filter string (needed when switching tabs)
+ mFilterSubString = search_string;
+ // Set filter string on active panel
+ panel->setFilterSubString(mFilterSubString);
+ }
+}
+
+void LLPanelMarketplaceListings::draw()
+{
+ if (LLMarketplaceData::instance().checkDirtyCount())
+ {
+ update_all_marketplace_count();
+ }
+
+ // Get the audit button enabled only after the whole inventory is fetched
+ if (!mAuditBtn->getEnabled())
+ {
+ mAuditBtn->setEnabled(LLInventoryModelBackgroundFetch::instance().isEverythingFetched());
+ }
+
+ LLPanel::draw();
+}
+
+void LLPanelMarketplaceListings::onSelectionChange(LLInventoryPanel *panel, const std::deque& items, BOOL user_action)
+{
+ panel->onSelectionChange(items, user_action);
+}
+
+bool LLPanelMarketplaceListings::allowDropOnRoot()
+{
+ LLInventoryPanel* panel = (LLInventoryPanel*)getChild("marketplace_filter_tabs")->getCurrentPanel();
+ return (panel ? panel->getAllowDropOnRoot() : false);
+}
+
+void LLPanelMarketplaceListings::onTabChange()
+{
+ // Find active panel
+ LLInventoryPanel* panel = (LLInventoryPanel*)getChild("marketplace_filter_tabs")->getCurrentPanel();
+ if (panel)
+ {
+ // If the panel doesn't allow drop on root, it doesn't allow the creation of new folder on root either
+ LLButton* add_btn = getChild("add_btn");
+ add_btn->setEnabled(panel->getAllowDropOnRoot());
+
+ // Set filter string on active panel
+ panel->setFilterSubString(mFilterSubString);
+
+ // Show/hide the drop zone and resize the inventory tabs panel accordingly
+ LLPanel* drop_zone = (LLPanel*)getChild("marketplace_drop_zone");
+ bool drop_zone_visible = drop_zone->getVisible();
+ bool allow_drop_on_root = panel->getAllowDropOnRoot() && gSavedSettings.getBOOL("LiruEnableWIPUI");
+ if (drop_zone_visible != allow_drop_on_root)
+ {
+ LLPanel* tabs = (LLPanel*)getChild("tab_container_panel");
+ S32 delta_height = drop_zone->getRect().getHeight();
+ delta_height = (drop_zone_visible ? delta_height : -delta_height);
+ tabs->reshape(tabs->getRect().getWidth(),tabs->getRect().getHeight() + delta_height);
+ tabs->translate(0,-delta_height);
+ }
+ drop_zone->setVisible(allow_drop_on_root);
+ }
+}
+
+void LLPanelMarketplaceListings::onAddButtonClicked()
+{
+ // Find active panel
+ LLInventoryPanel* panel = (LLInventoryPanel*)getChild("marketplace_filter_tabs")->getCurrentPanel();
+ if (panel)
+ {
+ LLUUID marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false);
+ llassert(marketplacelistings_id.notNull());
+ LLFolderType::EType preferred_type = LLFolderType::lookup("category");
+ LLUUID category = gInventory.createNewCategory(marketplacelistings_id, preferred_type, LLStringUtil::null);
+ gInventory.notifyObservers();
+ panel->setSelectionByID(category, TRUE);
+ panel->getRootFolder()->setNeedsAutoRename(TRUE);
+ }
+}
+
+void LLPanelMarketplaceListings::onAuditButtonClicked()
+{
+ LLSD data(LLSD::emptyMap());
+ new LLFloaterMarketplaceValidation(data); // It tracks itself *sigh*
+}
+
+void LLPanelMarketplaceListings::onViewSortMenuItemClicked(const LLSD& userdata)
+{
+ std::string chosen_item = userdata.asString();
+
+ // Sort options
+ if ((chosen_item == "sort_by_stock_amount") || (chosen_item == "sort_by_name") || (chosen_item == "sort_by_recent"))
+ {
+ // We're making sort options exclusive, default is SO_FOLDERS_BY_NAME
+ if (chosen_item == "sort_by_stock_amount")
+ {
+ setSortOrder(LLInventoryFilter::SO_FOLDERS_BY_WEIGHT);
+ }
+ else if (chosen_item == "sort_by_name")
+ {
+ setSortOrder(LLInventoryFilter::SO_FOLDERS_BY_NAME);
+ }
+ else if (chosen_item == "sort_by_recent")
+ {
+ setSortOrder(LLInventoryFilter::SO_DATE);
+ }
+ }
+ // Filter option
+ else if (chosen_item == "show_only_listing_folders")
+ {
+ mFilterListingFoldersOnly = !mFilterListingFoldersOnly;
+ // Set each panel with that filter flag
+ LLTabContainer* tabs_panel = getChild("marketplace_filter_tabs");
+ LLInventoryPanel* panel = (LLInventoryPanel*)tabs_panel->getPanelByName("All Items");
+ panel->getFilter().setFilterMarketplaceListingFolders(mFilterListingFoldersOnly);
+ panel = (LLInventoryPanel*)tabs_panel->getPanelByName("Active Items");
+ panel->getFilter().setFilterMarketplaceListingFolders(mFilterListingFoldersOnly);
+ panel = (LLInventoryPanel*)tabs_panel->getPanelByName("Inactive Items");
+ panel->getFilter().setFilterMarketplaceListingFolders(mFilterListingFoldersOnly);
+ panel = (LLInventoryPanel*)tabs_panel->getPanelByName("Unassociated Items");
+ panel->getFilter().setFilterMarketplaceListingFolders(mFilterListingFoldersOnly);
+ }
+}
+
+bool LLPanelMarketplaceListings::onViewSortMenuItemCheck(const LLSD& userdata)
+{
+ std::string chosen_item = userdata.asString();
+
+ if ((chosen_item == "sort_by_stock_amount") || (chosen_item == "sort_by_name") || (chosen_item == "sort_by_recent"))
+ {
+ if (chosen_item == "sort_by_stock_amount")
+ {
+ return (mSortOrder & LLInventoryFilter::SO_FOLDERS_BY_WEIGHT);
+ }
+ else if (chosen_item == "sort_by_name")
+ {
+ return (mSortOrder & LLInventoryFilter::SO_FOLDERS_BY_NAME);
+ }
+ else if (chosen_item == "sort_by_recent")
+ {
+ return (mSortOrder & LLInventoryFilter::SO_DATE);
+ }
+ }
+ else if (chosen_item == "show_only_listing_folders")
+ {
+ return mFilterListingFoldersOnly;
+ }
+ return false;
+}
+
+///----------------------------------------------------------------------------
+/// LLMarketplaceListingsAddedObserver helper class
+///----------------------------------------------------------------------------
+
+class LLMarketplaceListingsAddedObserver : public LLInventoryCategoryAddedObserver
+{
+public:
+ LLMarketplaceListingsAddedObserver(LLFloaterMarketplaceListings * marketplace_listings_floater)
+ : LLInventoryCategoryAddedObserver()
+ , mMarketplaceListingsFloater(marketplace_listings_floater)
+ {
+ }
+
+ void done()
+ {
+ for (cat_vec_t::iterator it = mAddedCategories.begin(); it != mAddedCategories.end(); ++it)
+ {
+ LLViewerInventoryCategory* added_category = *it;
+
+ LLFolderType::EType added_category_type = added_category->getPreferredType();
+
+ if (added_category_type == LLFolderType::FT_MARKETPLACE_LISTINGS)
+ {
+ mMarketplaceListingsFloater->initializeMarketPlace();
+ }
+ }
+ }
+
+private:
+ LLFloaterMarketplaceListings * mMarketplaceListingsFloater;
+};
+
+///----------------------------------------------------------------------------
+/// LLFloaterMarketplaceListings
+///----------------------------------------------------------------------------
+
+LLFloaterMarketplaceListings::LLFloaterMarketplaceListings(const LLSD& key)
+: LLFloater(key)
+, mCategoriesObserver(NULL)
+, mCategoryAddedObserver(NULL)
+, mRootFolderId(LLUUID::null)
+, mInventoryStatus(NULL)
+, mInventoryInitializationInProgress(NULL)
+, mInventoryPlaceholder(NULL)
+, mInventoryText(NULL)
+, mInventoryTitle(NULL)
+, mPanelListings(NULL)
+, mPanelListingsSet(false)
+{
+ //buildFromFile("floater_marketplace_listings.xml");
+ mFactoryMap["panel_marketplace_listing"] = LLCallbackMap([&](void*) { return mPanelListings = new LLPanelMarketplaceListings; });
+ LLUICtrlFactory::instance().buildFloater(this, "floater_marketplace_listings.xml", &getFactoryMap());
+}
+
+LLFloaterMarketplaceListings::~LLFloaterMarketplaceListings()
+{
+ if (mCategoriesObserver && gInventory.containsObserver(mCategoriesObserver))
+ {
+ gInventory.removeObserver(mCategoriesObserver);
+ }
+ delete mCategoriesObserver;
+
+ if (mCategoryAddedObserver && gInventory.containsObserver(mCategoryAddedObserver))
+ {
+ gInventory.removeObserver(mCategoryAddedObserver);
+ }
+ delete mCategoryAddedObserver;
+}
+
+BOOL LLFloaterMarketplaceListings::postBuild()
+{
+ mInventoryStatus = getChild("marketplace_status");
+ mInventoryInitializationInProgress = getChild("initialization_progress_indicator");
+ mInventoryPlaceholder = getChild