diff options
298 files changed, 8146 insertions, 3814 deletions
diff --git a/BuildParams b/BuildParams index c5f96d5ee3..c5f96d5ee3 100755..100644 --- a/BuildParams +++ b/BuildParams diff --git a/autobuild.xml b/autobuild.xml index 2470b2e5aa..eb057ec8e0 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -2187,18 +2187,18 @@              <key>archive</key>              <map>                <key>hash</key> -              <string>40a87f5d505a141b2ec79513a6197c35</string> +              <string>0a6349b11c8e9d34f0c80b8081736e75</string>                <key>hash_algorithm</key>                <string>md5</string>                <key>url</key> -              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/76516/728250/llca-202102021657.555615-common-555615.tar.bz2</string> +              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/79438/751815/llca-202104010215.557744-common-557744.tar.bz2</string>              </map>              <key>name</key>              <string>common</string>            </map>          </map>          <key>version</key> -        <string>202102021657.555615</string> +        <string>202104010215.557744</string>        </map>        <key>llphysicsextensions_source</key>        <map> @@ -129,11 +129,6 @@ pre_build()      then # show that we're doing this, just not the contents           echo source "$bugsplat_sh"           source "$bugsplat_sh" -         # important: we test this and use its value in [grand-]child processes -         if [ -n "${BUGSPLAT_DB:-}" ] -         then echo export BUGSPLAT_DB -              export BUGSPLAT_DB -         fi      fi      set -x @@ -429,6 +424,15 @@ then    fi  fi +# Some of the uploads takes a long time to finish in the codeticket backend, +# causing the next codeticket upload attempt to fail. +# Inserting this after each potentially large upload may prevent those errors. +# JJ is making changes to Codeticket that we hope will eliminate this failure, then this can be removed +wait_for_codeticket() +{ +    sleep $(( 60 * 6 )) +} +  # check status and upload results to S3  if $succeeded  then @@ -445,6 +449,7 @@ then        # Upload base package.        python_cmd "$helpers/codeticket.py" addoutput Installer "$package"  \            || fatal "Upload of installer failed" +      wait_for_codeticket        # Upload additional packages.        for package_id in $additional_packages @@ -454,6 +459,7 @@ then          then            python_cmd "$helpers/codeticket.py" addoutput "Installer $package_id" "$package" \                || fatal "Upload of installer $package_id failed" +          wait_for_codeticket          else            record_failure "Failed to find additional package for '$package_id'."          fi @@ -467,6 +473,7 @@ then                # Upload crash reporter file                python_cmd "$helpers/codeticket.py" addoutput "Symbolfile" "$VIEWER_SYMBOL_FILE" \                    || fatal "Upload of symbolfile failed" +              wait_for_codeticket            fi            # Upload the llphysicsextensions_tpv package, if one was produced @@ -474,6 +481,9 @@ then            if [ -r "$build_dir/llphysicsextensions_package" ]            then                llphysicsextensions_package=$(cat $build_dir/llphysicsextensions_package) +              # This next upload is a frequent failure; see if giving the last one some time helps +              # JJ is making changes to Codeticket that we hope will eliminate this failure soon +              sleep 300                python_cmd "$helpers/codeticket.py" addoutput "Physics Extensions Package" "$llphysicsextensions_package" --private \                    || fatal "Upload of physics extensions package failed"            fi @@ -486,6 +496,7 @@ then                begin_section "Upload Extension $extension"                . $extension                [ $? -eq 0 ] || fatal "Upload of extension $extension failed" +              wait_for_codeticket                end_section "Upload Extension $extension"            done        fi @@ -495,7 +506,6 @@ then      record_event "skipping upload of installer"    fi -    else      record_event "skipping upload of installer due to failed build"  fi diff --git a/doc/contributions.txt b/doc/contributions.txt index 885665dd6f..8039e99f87 100755 --- a/doc/contributions.txt +++ b/doc/contributions.txt @@ -227,6 +227,7 @@ Ansariel Hiller  	SL-13364  	SL-13858  	SL-13697 +	SL-13395  	SL-3136  Aralara Rajal  Arare Chantilly @@ -269,6 +270,7 @@ Beq Janus      SL-11300  	SL-13583  	SL-14766 +	SL-14927  Beth Walcher  Bezilon Kasei  Biancaluce Robbiani @@ -361,6 +363,8 @@ Chaser Zaks      BUG-227485  Cherry Cheevers  ChickyBabes Zuzu +Chorazin Allen +    BUG-229753  Christopher  Organiser  Ciaran Laval  Cinder Roxley diff --git a/indra/CMakeLists.txt b/indra/CMakeLists.txt index 53e5d7b6a5..db88e44127 100644 --- a/indra/CMakeLists.txt +++ b/indra/CMakeLists.txt @@ -13,6 +13,7 @@ project(${ROOT_PROJECT_NAME})  set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")  include(Variables) +include(bugsplat)  include(BuildVersion)  set(LEGACY_STDIO_LIBS) @@ -50,7 +51,10 @@ endif (WINDOWS AND EXISTS ${LIBS_CLOSED_DIR}copy_win_scripts)  add_custom_target(viewer) +if (NOT USE_BUGSPLAT)  add_subdirectory(${LIBS_OPEN_PREFIX}llcrashlogger) +endif (NOT USE_BUGSPLAT) +  add_subdirectory(${LIBS_OPEN_PREFIX}llplugin)  add_subdirectory(${LIBS_OPEN_PREFIX}llui)  add_subdirectory(${LIBS_OPEN_PREFIX}viewer_components) @@ -64,29 +68,18 @@ add_subdirectory(${LIBS_OPEN_PREFIX}media_plugins)  endif (ENABLE_MEDIA_PLUGINS)  if (LINUX) -  add_subdirectory(${VIEWER_PREFIX}linux_crash_logger)    if (INSTALL_PROPRIETARY)        include(LLAppearanceUtility)        add_subdirectory(${LLAPPEARANCEUTILITY_SRC_DIR} ${LLAPPEARANCEUTILITY_BIN_DIR})    endif (INSTALL_PROPRIETARY) -  add_dependencies(viewer linux-crash-logger-strip-target) -elseif (DARWIN) -  add_subdirectory(${VIEWER_PREFIX}mac_crash_logger) -  add_dependencies(viewer mac-crash-logger) -elseif (WINDOWS) -  add_subdirectory(${VIEWER_PREFIX}win_crash_logger) -  # cmake EXISTS requires an absolute path, see indra/cmake/Variables.cmake -  if (EXISTS ${VIEWER_DIR}win_setup) -    add_subdirectory(${VIEWER_DIR}win_setup) -  endif (EXISTS ${VIEWER_DIR}win_setup) -  # add_dependencies(viewer windows-setup windows-crash-logger) -  add_dependencies(viewer windows-crash-logger)  endif (LINUX) -add_subdirectory(${VIEWER_PREFIX}newview) -add_dependencies(viewer secondlife-bin) - -add_subdirectory(${VIEWER_PREFIX}doxygen EXCLUDE_FROM_ALL) +if (WINDOWS) +    # cmake EXISTS requires an absolute path, see indra/cmake/Variables.cmake +    if (EXISTS ${VIEWER_DIR}win_setup) +      add_subdirectory(${VIEWER_DIR}win_setup) +    endif (EXISTS ${VIEWER_DIR}win_setup) +endif (WINDOWS)  # sets the 'startup project' for debugging from visual studio.  set_property( @@ -94,6 +87,32 @@ set_property(      PROPERTY VS_STARTUP_PROJECT secondlife-bin      ) +if (USE_BUGSPLAT) +    if (BUGSPLAT_DB) +        message(STATUS "Building with BugSplat; database '${BUGSPLAT_DB}'") +    else (BUGSPLAT_DB) +        message(WARNING "Building with BugSplat, but no database name set (BUGSPLAT_DB)") +    endif (BUGSPLAT_DB) +else (USE_BUGSPLAT) +    message(STATUS "Not building with BugSplat") +    if (LINUX) +      add_subdirectory(${VIEWER_PREFIX}linux_crash_logger) +      add_dependencies(viewer linux-crash-logger-strip-target) +    elseif (DARWIN) +      add_subdirectory(${VIEWER_PREFIX}mac_crash_logger) +      add_dependencies(viewer mac-crash-logger) +    elseif (WINDOWS) +      add_subdirectory(${VIEWER_PREFIX}win_crash_logger) +      # add_dependencies(viewer windows-setup windows-crash-logger) +      add_dependencies(viewer windows-crash-logger) +    endif (LINUX) +endif (USE_BUGSPLAT) + +add_subdirectory(${VIEWER_PREFIX}newview) +add_dependencies(viewer secondlife-bin) + +add_subdirectory(${VIEWER_PREFIX}doxygen EXCLUDE_FROM_ALL) +  if (LL_TESTS)    # Define after the custom targets are created so    # individual apps can add themselves as dependencies diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake index de81512eef..46ddb9d15b 100644 --- a/indra/cmake/Copy3rdPartyLibs.cmake +++ b/indra/cmake/Copy3rdPartyLibs.cmake @@ -66,7 +66,7 @@ if(WINDOWS)      # Filenames are different for 32/64 bit BugSplat file and we don't      # have any control over them so need to branch. -    if (BUGSPLAT_DB) +    if (USE_BUGSPLAT)        if(ADDRESS_SIZE EQUAL 32)          set(release_files ${release_files} BugSplat.dll)          set(release_files ${release_files} BugSplatRc.dll) @@ -76,7 +76,7 @@ if(WINDOWS)          set(release_files ${release_files} BugSplatRc64.dll)          set(release_files ${release_files} BsSndRpt64.exe)        endif(ADDRESS_SIZE EQUAL 32) -    endif (BUGSPLAT_DB) +    endif (USE_BUGSPLAT)      if (FMODSTUDIO)          set(debug_files ${debug_files} fmodL.dll) diff --git a/indra/cmake/LLAddBuildTest.cmake b/indra/cmake/LLAddBuildTest.cmake index 4932e9044f..4937c2a9d7 100644 --- a/indra/cmake/LLAddBuildTest.cmake +++ b/indra/cmake/LLAddBuildTest.cmake @@ -2,6 +2,7 @@  include(00-Common)  include(LLTestCommand)  include(GoogleMock) +include(bugsplat)  include(Tut)  #***************************************************************************** @@ -22,7 +23,6 @@ MACRO(LL_ADD_PROJECT_UNIT_TESTS project sources)    # there is another branch that will conflict heavily with any changes here.  INCLUDE(GoogleMock) -    IF(LL_TEST_VERBOSE)      MESSAGE("LL_ADD_PROJECT_UNIT_TESTS UNITTEST_PROJECT_${project} sources: ${sources}")    ENDIF(LL_TEST_VERBOSE) @@ -87,6 +87,12 @@ INCLUDE(GoogleMock)      IF(LL_TEST_VERBOSE)        MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_SOURCE_FILES ${${name}_test_SOURCE_FILES}")      ENDIF(LL_TEST_VERBOSE) + +    if (USE_BUGSPLAT) +      SET_PROPERTY(SOURCE ${${name}_test_SOURCE_FILES} +          APPEND PROPERTY COMPILE_DEFINITIONS "${BUGSPLAT_DEFINE}") +    endif (USE_BUGSPLAT) +      # Headers      GET_OPT_SOURCE_FILE_PROPERTY(${name}_test_additional_HEADER_FILES ${source} LL_TEST_ADDITIONAL_HEADER_FILES)      SET(${name}_test_HEADER_FILES ${name}.h ${${name}_test_additional_HEADER_FILES}) @@ -224,6 +230,11 @@ FUNCTION(LL_ADD_INTEGRATION_TEST      SET_TARGET_PROPERTIES(INTEGRATION_TEST_${testname} PROPERTIES COMPILE_FLAGS -I"${TUT_INCLUDE_DIR}")    endif(USESYSTEMLIBS) +  if (USE_BUGSPLAT) +      SET_PROPERTY(SOURCE ${source_files} +          APPEND PROPERTY COMPILE_DEFINITIONS "${BUGSPLAT_DEFINE}") +  endif (USE_BUGSPLAT) +    # The following was copied to llcorehttp/CMakeLists.txt's texture_load target.     # Any changes made here should be replicated there.    if (WINDOWS) diff --git a/indra/cmake/Variables.cmake b/indra/cmake/Variables.cmake index a5770c5528..c81b22e572 100644 --- a/indra/cmake/Variables.cmake +++ b/indra/cmake/Variables.cmake @@ -34,7 +34,6 @@ set(LL_TESTS ON CACHE BOOL "Build and run unit and integration tests (disable fo  set(INCREMENTAL_LINK OFF CACHE BOOL "Use incremental linking on win32 builds (enable for faster links on some machines)")  set(ENABLE_MEDIA_PLUGINS ON CACHE BOOL "Turn off building media plugins if they are imported by third-party library mechanism")  set(VIEWER_SYMBOL_FILE "" CACHE STRING "Name of tarball into which to place symbol files") -set(BUGSPLAT_DB "" CACHE STRING "BugSplat database name, if BugSplat crash reporting is desired")  if(LIBS_CLOSED_DIR)    file(TO_CMAKE_PATH "${LIBS_CLOSED_DIR}" LIBS_CLOSED_DIR) diff --git a/indra/cmake/bugsplat.cmake b/indra/cmake/bugsplat.cmake index 59644b73ce..4edc4c59cd 100644 --- a/indra/cmake/bugsplat.cmake +++ b/indra/cmake/bugsplat.cmake @@ -1,25 +1,37 @@ -# BugSplat is engaged by setting BUGSPLAT_DB to the target BugSplat database -# name. -if (BUGSPLAT_DB) -  if (USESYSTEMLIBS) -    message(STATUS "Looking for system BugSplat") -    set(BUGSPLAT_FIND_QUIETLY ON) -    set(BUGSPLAT_FIND_REQUIRED ON) -    include(FindBUGSPLAT) -  else (USESYSTEMLIBS) -    message(STATUS "Engaging autobuild BugSplat") -    include(Prebuilt) -    use_prebuilt_binary(bugsplat) -    if (WINDOWS) -      set(BUGSPLAT_LIBRARIES  -        ${ARCH_PREBUILT_DIRS_RELEASE}/bugsplat.lib -        ) -    elseif (DARWIN) -      find_library(BUGSPLAT_LIBRARIES BugsplatMac -        PATHS "${ARCH_PREBUILT_DIRS_RELEASE}") -    else (WINDOWS) +if (INSTALL_PROPRIETARY) +    # Note that viewer_manifest.py makes decision based on BUGSPLAT_DB and not USE_BUGSPLAT +    if (BUGSPLAT_DB) +        set(USE_BUGSPLAT ON  CACHE BOOL "Use the BugSplat crash reporting system") +    else (BUGSPLAT_DB) +        set(USE_BUGSPLAT OFF CACHE BOOL "Use the BugSplat crash reporting system") +    endif (BUGSPLAT_DB) +else (INSTALL_PROPRIETARY) +    set(USE_BUGSPLAT OFF CACHE BOOL "Use the BugSplat crash reporting system") +endif (INSTALL_PROPRIETARY) + +if (USE_BUGSPLAT) +    if (NOT USESYSTEMLIBS) +        include(Prebuilt) +        use_prebuilt_binary(bugsplat) +        if (WINDOWS) +            set(BUGSPLAT_LIBRARIES  +                ${ARCH_PREBUILT_DIRS_RELEASE}/bugsplat.lib +                ) +        elseif (DARWIN) +            find_library(BUGSPLAT_LIBRARIES BugsplatMac REQUIRED +                NO_DEFAULT_PATH PATHS "${ARCH_PREBUILT_DIRS_RELEASE}") +        else (WINDOWS) +            message(FATAL_ERROR "BugSplat is not supported; add -DUSE_BUGSPLAT=OFF") +        endif (WINDOWS) +    else (NOT USESYSTEMLIBS) +        set(BUGSPLAT_FIND_QUIETLY ON) +        set(BUGSPLAT_FIND_REQUIRED ON) +        include(FindBUGSPLAT) +    endif (NOT USESYSTEMLIBS) + +    set(BUGSPLAT_DB "" CACHE STRING "BugSplat crash database name") -    endif (WINDOWS)      set(BUGSPLAT_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/bugsplat) -  endif (USESYSTEMLIBS) -endif (BUGSPLAT_DB) +    set(BUGSPLAT_DEFINE "LL_BUGSPLAT") +endif (USE_BUGSPLAT) + diff --git a/indra/linux_crash_logger/README.txt b/indra/linux_crash_logger/README.txt new file mode 100644 index 0000000000..6932a8d9c3 --- /dev/null +++ b/indra/linux_crash_logger/README.txt @@ -0,0 +1,3 @@ +This component is no longer used in Linden Lab builds. +Change requests to support continued use by open source +builds are welcome. diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index cecfadcd91..dd266630ea 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -4,6 +4,7 @@ project(llcommon)  include(00-Common)  include(LLCommon) +include(bugsplat)  include(Linking)  include(Boost)  include(LLSharedLibs) @@ -260,10 +261,10 @@ set(llcommon_HEADER_FILES  set_source_files_properties(${llcommon_HEADER_FILES}                              PROPERTIES HEADER_FILE_ONLY TRUE) -if (BUGSPLAT_DB) -  set_source_files_properties(llapp.cpp -    PROPERTIES COMPILE_DEFINITIONS "LL_BUGSPLAT") -endif (BUGSPLAT_DB) +if (USE_BUGSPLAT) +  set_source_files_properties(${llcommon_SOURCE_FILES} +    PROPERTIES COMPILE_DEFINITIONS "${BUGSPLAT_DEFINE}") +endif (USE_BUGSPLAT)  list(APPEND llcommon_SOURCE_FILES ${llcommon_HEADER_FILES}) diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp index a90b294550..6064a843ae 100644 --- a/indra/llcommon/llapp.cpp +++ b/indra/llcommon/llapp.cpp @@ -528,7 +528,12 @@ void LLApp::setupErrorHandling(bool second_instance)  #endif // LL_LINUX  #endif // ! LL_WINDOWS + +#ifdef LL_BUGSPLAT +    // do not start our own error thread +#else // ! LL_BUGSPLAT  	startErrorThread(); +#endif  }  void LLApp::startErrorThread() @@ -808,7 +813,9 @@ void setup_signals()  	act.sa_flags = SA_SIGINFO;  	// Synchronous signals +#   ifndef LL_BUGSPLAT  	sigaction(SIGABRT, &act, NULL); +#   endif  	sigaction(SIGALRM, &act, NULL);  	sigaction(SIGBUS, &act, NULL);  	sigaction(SIGFPE, &act, NULL); @@ -845,7 +852,9 @@ void clear_signals()  	act.sa_flags = SA_SIGINFO;  	// Synchronous signals +#   ifndef LL_BUGSPLAT  	sigaction(SIGABRT, &act, NULL); +#   endif  	sigaction(SIGALRM, &act, NULL);  	sigaction(SIGBUS, &act, NULL);  	sigaction(SIGFPE, &act, NULL); @@ -898,6 +907,7 @@ void default_unix_signal_handler(int signum, siginfo_t *info, void *)  		return;  	case SIGABRT: +        // Note that this handler is not set for SIGABRT when using Bugsplat  		// Abort just results in termination of the app, no funky error handling.  		if (LLApp::sLogInSignal)  		{ diff --git a/indra/llcommon/llapp.h b/indra/llcommon/llapp.h index 245c73e3a2..5fa91b8bf5 100644 --- a/indra/llcommon/llapp.h +++ b/indra/llcommon/llapp.h @@ -259,6 +259,10 @@ public:  	  */  	LLRunner& getRunner() { return mRunner; } +#ifdef LL_WINDOWS +    virtual void reportCrashToBugsplat(void* pExcepInfo /*EXCEPTION_POINTERS*/) { } +#endif +  public:  	typedef std::map<std::string, std::string> string_map;  	string_map mOptionMap;	// Contains all command-line options and arguments in a map diff --git a/indra/llcommon/llcoros.cpp b/indra/llcommon/llcoros.cpp index 23419a52a7..111c50af93 100644 --- a/indra/llcommon/llcoros.cpp +++ b/indra/llcommon/llcoros.cpp @@ -56,6 +56,10 @@  #include "stringize.h"  #include "llexception.h" +#if LL_WINDOWS +#include <excpt.h> +#endif +  // static  LLCoros::CoroData& LLCoros::get_CoroData(const std::string& caller)  { @@ -249,29 +253,58 @@ std::string LLCoros::launch(const std::string& prefix, const callable_t& callabl  #if LL_WINDOWS -void LLCoros::winlevel(const callable_t& callable) +static const U32 STATUS_MSC_EXCEPTION = 0xE06D7363; // compiler specific + +U32 cpp_exception_filter(U32 code, struct _EXCEPTION_POINTERS *exception_infop, const std::string& name) +{ +    // C++ exceptions were logged in toplevelTryWrapper, but not SEH +    // log SEH exceptions here, to make sure it gets into bugsplat's  +    // report and because __try won't allow std::string operations +    if (code != STATUS_MSC_EXCEPTION) +    { +        LL_WARNS() << "SEH crash in " << name << ", code: " << code << LL_ENDL; +    } +    // Handle bugsplat here, since GetExceptionInformation() can only be +    // called from within filter for __except(filter), not from __except's {} +    // Bugsplat should get all exceptions, C++ and SEH +    LLApp::instance()->reportCrashToBugsplat(exception_infop); + +    // Only convert non C++ exceptions. +    if (code == STATUS_MSC_EXCEPTION) +    { +        // C++ exception, go on +        return EXCEPTION_CONTINUE_SEARCH; +    } +    else +    { +        // handle it +        return EXCEPTION_EXECUTE_HANDLER; +    } +} + +void LLCoros::winlevel(const std::string& name, const callable_t& callable)  {      __try      { -        callable(); +        toplevelTryWrapper(name, callable);      } -    __except (msc_exception_filter(GetExceptionCode(), GetExceptionInformation())) +    __except (cpp_exception_filter(GetExceptionCode(), GetExceptionInformation(), name))      { -        // convert to C++ styled exception +        // convert to C++ styled exception for handlers other than bugsplat          // Note: it might be better to use _se_set_translator          // if you want exception to inherit full callstack -        char integer_string[32]; -        sprintf(integer_string, "SEH, code: %lu\n", GetExceptionCode()); +        // +        // in case of bugsplat this will get to exceptionTerminateHandler and +        // looks like fiber will terminate application after that +        char integer_string[512]; +        sprintf(integer_string, "SEH crash in %s, code: %lu\n", name.c_str(), GetExceptionCode());          throw std::exception(integer_string);      }  }  #endif -// Top-level wrapper around caller's coroutine callable. -// Normally we like to pass strings and such by const reference -- but in this -// case, we WANT to copy both the name and the callable to our local stack! -void LLCoros::toplevel(std::string name, callable_t callable) +void LLCoros::toplevelTryWrapper(const std::string& name, const callable_t& callable)  {      // keep the CoroData on this top-level function's stack frame      CoroData corodata(name); @@ -281,16 +314,12 @@ void LLCoros::toplevel(std::string name, callable_t callable)      // run the code the caller actually wants in the coroutine      try      { -#if LL_WINDOWS && LL_RELEASE_FOR_DOWNLOAD -        winlevel(callable); -#else          callable(); -#endif      }      catch (const Stop& exc)      {          LL_INFOS("LLCoros") << "coroutine " << name << " terminating because " -                            << exc.what() << LL_ENDL; +            << exc.what() << LL_ENDL;      }      catch (const LLContinueError&)      { @@ -303,10 +332,25 @@ void LLCoros::toplevel(std::string name, callable_t callable)      {          // Any OTHER kind of uncaught exception will cause the viewer to          // crash, hopefully informatively. -        CRASH_ON_UNHANDLED_EXCEPTION(STRINGIZE("coroutine " << name)); +        LOG_UNHANDLED_EXCEPTION(STRINGIZE("coroutine " << name)); +        // to not modify callstack +        throw;      }  } +// Top-level wrapper around caller's coroutine callable. +// Normally we like to pass strings and such by const reference -- but in this +// case, we WANT to copy both the name and the callable to our local stack! +void LLCoros::toplevel(std::string name, callable_t callable) +{ +#if LL_WINDOWS +    // Can not use __try in functions that require unwinding, so use one more wrapper +    winlevel(name, callable); +#else +    toplevelTryWrapper(name, callable); +#endif +} +  //static  void LLCoros::checkStop()  { diff --git a/indra/llcommon/llcoros.h b/indra/llcommon/llcoros.h index 38c2356c99..6c0bec3ef9 100644 --- a/indra/llcommon/llcoros.h +++ b/indra/llcommon/llcoros.h @@ -290,11 +290,12 @@ public:  private:      std::string generateDistinctName(const std::string& prefix) const; -    void toplevel(std::string name, callable_t callable); -    struct CoroData;  #if LL_WINDOWS -    static void winlevel(const callable_t& callable); +    void winlevel(const std::string& name, const callable_t& callable);  #endif +    void toplevelTryWrapper(const std::string& name, const callable_t& callable); +    void toplevel(std::string name, callable_t callable); +    struct CoroData;      static CoroData& get_CoroData(const std::string& caller);      S32 mStackSize; diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp index f876b8ee4a..8355df9045 100644 --- a/indra/llcommon/llerror.cpp +++ b/indra/llcommon/llerror.cpp @@ -442,8 +442,6 @@ namespace      protected:  		Globals();  	public: -		std::ostringstream messageStream; -		bool messageStreamInUse;  		std::string mFatalMessage;  		void addCallSite(LLError::CallSite&); @@ -453,12 +451,7 @@ namespace  		CallSiteVector callSites;  	}; -	Globals::Globals() -		: messageStream(), -		messageStreamInUse(false), -		callSites() -	{ -	} +	Globals::Globals() {}      Globals* Globals::getInstance()      { @@ -549,7 +542,7 @@ namespace LLError  		mFileLevelMap(),  		mTagLevelMap(),  		mUniqueLogMessages(), -		mCrashFunction(NULL), +		mCrashFunction([](const std::string&){}),  		mTimeFunction(NULL),  		mRecorders(),  		mShouldLogCallCounter(0) @@ -728,7 +721,6 @@ namespace  		LLError::setDefaultLevel(LLError::LEVEL_INFO);  		LLError::setAlwaysFlush(true);  		LLError::setEnabledLogTypesMask(0xFFFFFFFF); -		LLError::setFatalFunction(LLError::crashAndLoop);  		LLError::setTimeFunction(LLError::utcTime);  		// log_to_stderr is only false in the unit and integration tests to keep builds quieter @@ -1360,57 +1352,7 @@ namespace LLError  	} -	std::ostringstream* Log::out() -	{ -		LLMutexTrylock lock(getMutex<LOG_MUTEX>(),5); - -		if (lock.isLocked()) -		{ -			Globals* g = Globals::getInstance(); - -			if (!g->messageStreamInUse) -			{ -				g->messageStreamInUse = true; -				return &g->messageStream; -			} -		} - -		return new std::ostringstream; -	} - -	void Log::flush(std::ostringstream* out, char* message) -	{ -		LLMutexTrylock lock(getMutex<LOG_MUTEX>(),5); -		if (!lock.isLocked()) -		{ -			return; -		} - -		if(strlen(out->str().c_str()) < 128) -		{ -			strcpy(message, out->str().c_str()); -		} -		else -		{ -			strncpy(message, out->str().c_str(), 127); -			message[127] = '\0' ; -		} - -		Globals* g = Globals::getInstance(); -		if (out == &g->messageStream) -		{ -			g->messageStream.clear(); -			g->messageStream.str(""); -			g->messageStreamInUse = false; -		} -		else -		{ -			delete out; -		} -		return ; -	} - -	void Log::flush(std::ostringstream* out, const CallSite& site) +	void Log::flush(const std::ostringstream& out, const CallSite& site)  	{  		LLMutexTrylock lock(getMutex<LOG_MUTEX>(),5);  		if (!lock.isLocked()) @@ -1421,22 +1363,11 @@ namespace LLError  		Globals* g = Globals::getInstance();  		SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig(); -		std::string message = out->str(); -		if (out == &g->messageStream) -		{ -			g->messageStream.clear(); -			g->messageStream.str(""); -			g->messageStreamInUse = false; -		} -		else -		{ -			delete out; -		} - +		std::string message = out.str();  		if (site.mPrintOnce)  		{ -            std::ostringstream message_stream; +			std::ostringstream message_stream;  			std::map<std::string, unsigned int>::iterator messageIter = s->mUniqueLogMessages.find(message);  			if (messageIter != s->mUniqueLogMessages.end()) @@ -1457,8 +1388,8 @@ namespace LLError  				message_stream << "ONCE: ";  				s->mUniqueLogMessages[message] = 1;  			} -            message_stream << message; -            message = message_stream.str(); +			message_stream << message; +			message = message_stream.str();  		}  		writeToRecorders(site, message); @@ -1466,10 +1397,7 @@ namespace LLError  		if (site.mLevel == LEVEL_ERROR)  		{  			g->mFatalMessage = message; -			if (s->mCrashFunction) -			{ -				s->mCrashFunction(message); -			} +			s->mCrashFunction(message);  		}  	}  } @@ -1533,29 +1461,6 @@ namespace LLError  		return s->mShouldLogCallCounter;  	} -#if LL_WINDOWS -		// VC80 was optimizing the error away. -		#pragma optimize("", off) -#endif -	void crashAndLoop(const std::string& message) -	{ -		// Now, we go kaboom! -		int* make_me_crash = NULL; - -		*make_me_crash = 0; - -		while(true) -		{ -			// Loop forever, in case the crash didn't work? -		} -		 -		// this is an attempt to let Coverity and other semantic scanners know that this function won't be returning ever. -		exit(EXIT_FAILURE); -	} -#if LL_WINDOWS -		#pragma optimize("", on) -#endif -  	std::string utcTime()  	{  		time_t now = time(NULL); @@ -1572,33 +1477,7 @@ namespace LLError  namespace LLError  {      -	char** LLCallStacks::sBuffer = NULL ; -	S32    LLCallStacks::sIndex  = 0 ; - -	//static -    void LLCallStacks::allocateStackBuffer() -    { -        if(sBuffer == NULL) -        { -            sBuffer = new char*[512] ; -            sBuffer[0] = new char[512 * 128] ; -            for(S32 i = 1 ; i < 512 ; i++) -            { -                sBuffer[i] = sBuffer[i-1] + 128 ; -            } -            sIndex = 0 ; -        } -    } - -    void LLCallStacks::freeStackBuffer() -    { -        if(sBuffer != NULL) -        { -            delete [] sBuffer[0] ; -            delete [] sBuffer ; -            sBuffer = NULL ; -        } -    } +    LLCallStacks::StringVector LLCallStacks::sBuffer ;      //static      void LLCallStacks::push(const char* function, const int line) @@ -1609,33 +1488,24 @@ namespace LLError              return;          } -        if(sBuffer == NULL) -        { -            allocateStackBuffer(); -        } - -        if(sIndex > 511) +        if(sBuffer.size() > 511)          {              clear() ;          } -        strcpy(sBuffer[sIndex], function) ; -        sprintf(sBuffer[sIndex] + strlen(function), " line: %d ", line) ; -        sIndex++ ; - -        return ; +        std::ostringstream out; +        insert(out, function, line); +        sBuffer.push_back(out.str());      }      //static -    std::ostringstream* LLCallStacks::insert(const char* function, const int line) +    void LLCallStacks::insert(std::ostream& out, const char* function, const int line)      { -        std::ostringstream* _out = LLError::Log::out(); -        *_out << function << " line " << line << " " ; -        return _out ; +        out << function << " line " << line << " " ;      }      //static -    void LLCallStacks::end(std::ostringstream* _out) +    void LLCallStacks::end(const std::ostringstream& out)      {          LLMutexTrylock lock(getMutex<STACKS_MUTEX>(), 5);          if (!lock.isLocked()) @@ -1643,17 +1513,12 @@ namespace LLError              return;          } -        if(sBuffer == NULL) -        { -            allocateStackBuffer(); -        } - -        if(sIndex > 511) +        if(sBuffer.size() > 511)          {              clear() ;          } -        LLError::Log::flush(_out, sBuffer[sIndex++]) ; +        sBuffer.push_back(out.str());      }      //static @@ -1665,33 +1530,30 @@ namespace LLError              return;          } -        if(sIndex > 0) +        if(! sBuffer.empty())          {              LL_INFOS() << " ************* PRINT OUT LL CALL STACKS ************* " << LL_ENDL; -            while(sIndex > 0) +            for (StringVector::const_reverse_iterator ri(sBuffer.rbegin()), re(sBuffer.rend()); +                 ri != re; ++ri)              {                   -                sIndex-- ; -                LL_INFOS() << sBuffer[sIndex] << LL_ENDL; +                LL_INFOS() << (*ri) << LL_ENDL;              }              LL_INFOS() << " *************** END OF LL CALL STACKS *************** " << LL_ENDL;          } -        if(sBuffer != NULL) -        { -            freeStackBuffer(); -        } +        cleanup();      }      //static      void LLCallStacks::clear()      { -        sIndex = 0 ; +        sBuffer.clear();      }      //static      void LLCallStacks::cleanup()      { -        freeStackBuffer(); +        clear();      }      std::ostream& operator<<(std::ostream& out, const LLStacktrace&) diff --git a/indra/llcommon/llerror.h b/indra/llcommon/llerror.h index ffaa464d77..d439136ca8 100644 --- a/indra/llcommon/llerror.h +++ b/indra/llcommon/llerror.h @@ -29,7 +29,9 @@  #define LL_LLERROR_H  #include <sstream> +#include <string>  #include <typeinfo> +#include <vector>  #include "stdtypes.h" @@ -198,9 +200,7 @@ namespace LLError  	{  	public:  		static bool shouldLog(CallSite&); -		static std::ostringstream* out(); -		static void flush(std::ostringstream* out, char* message); -		static void flush(std::ostringstream*, const CallSite&); +		static void flush(const std::ostringstream&, const CallSite&);  		static std::string demangle(const char* mangled);  		/// classname<TYPE>()  		template <typename T> @@ -281,18 +281,15 @@ namespace LLError      class LL_COMMON_API LLCallStacks      {      private: -        static char**  sBuffer ; -        static S32     sIndex ; - -        static void allocateStackBuffer(); -        static void freeStackBuffer(); +        typedef std::vector<std::string> StringVector; +        static StringVector sBuffer ;      public:             static void push(const char* function, const int line) ; -        static std::ostringstream* insert(const char* function, const int line) ; +        static void insert(std::ostream& out, const char* function, const int line) ;          static void print() ;          static void clear() ; -        static void end(std::ostringstream* _out) ; +        static void end(const std::ostringstream& out) ;          static void cleanup();      }; @@ -306,10 +303,11 @@ namespace LLError  //this is cheaper than llcallstacks if no need to output other variables to call stacks.   #define LL_PUSH_CALLSTACKS() LLError::LLCallStacks::push(__FUNCTION__, __LINE__) -#define llcallstacks                                                                      \ -	{                                                                                     \ -       std::ostringstream* _out = LLError::LLCallStacks::insert(__FUNCTION__, __LINE__) ; \ -       (*_out) +#define llcallstacks                                                    \ +	{                                                                   \ +		std::ostringstream _out;                                        \ +		LLError::LLCallStacks::insert(_out, __FUNCTION__, __LINE__) ;   \ +		_out  #define llcallstacksendl                   \  		LLError::End();                    \ @@ -355,11 +353,11 @@ typedef LLError::NoClassInfo _LL_CLASS_TO_LOG;  		static LLError::CallSite _site(lllog_site_args_(level, once, tags)); \  		lllog_test_() -#define lllog_test_()                                       \ -		if (LL_UNLIKELY(_site.shouldLog()))                 \ -		{                                                   \ -			std::ostringstream* _out = LLError::Log::out(); \ -			(*_out) +#define lllog_test_()                           \ +		if (LL_UNLIKELY(_site.shouldLog()))     \ +		{                                       \ +			std::ostringstream _out;            \ +			_out  #define lllog_site_args_(level, once, tags)                 \  	level, __FILE__, __LINE__, typeid(_LL_CLASS_TO_LOG),    \ @@ -378,15 +376,27 @@ typedef LLError::NoClassInfo _LL_CLASS_TO_LOG;  //	LL_CONT << " for " << t << " seconds" << LL_ENDL;  //	  //Such computation is done iff the message will be logged. -#define LL_CONT	(*_out) +#define LL_CONT	_out  #define LL_NEWLINE '\n' -#define LL_ENDL                               \ -			LLError::End();                   \ -			LLError::Log::flush(_out, _site); \ -		}                                     \ -	} while(0) +// Use this only in LL_ERRS or in a place that LL_ERRS may not be used +#define LLERROR_CRASH         \ +{                             \ +    int* make_me_crash = NULL;\ +    *make_me_crash = 0;       \ +    exit(*make_me_crash);     \ +} + +#define LL_ENDL                                         \ +            LLError::End();                             \ +            LLError::Log::flush(_out, _site);           \ +            if (_site.mLevel == LLError::LEVEL_ERROR)   \ +            {                                           \ +                LLERROR_CRASH                           \ +            }                                           \ +        }                                               \ +    } while(0)  // NEW Macros for debugging, allow the passing of a string tag diff --git a/indra/llcommon/llerrorcontrol.h b/indra/llcommon/llerrorcontrol.h index 25786d5457..e87bb7bf35 100644 --- a/indra/llcommon/llerrorcontrol.h +++ b/indra/llcommon/llerrorcontrol.h @@ -94,14 +94,16 @@ namespace LLError  	*/  	typedef boost::function<void(const std::string&)> FatalFunction; -	LL_COMMON_API void crashAndLoop(const std::string& message); -		// Default fatal function: access null pointer and loops forever  	LL_COMMON_API void setFatalFunction(const FatalFunction&); -		// The fatal function will be called when an message of LEVEL_ERROR +		// The fatal function will be called after an message of LEVEL_ERROR  		// is logged.  Note: supressing a LEVEL_ERROR message from being logged  		// (by, for example, setting a class level to LEVEL_NONE), will keep -		// the that message from causing the fatal funciton to be invoked. +		// that message from causing the fatal function to be invoked. +		// The passed FatalFunction will be the LAST log function called +		// before LL_ERRS crashes its caller. A FatalFunction can throw an +		// exception, or call exit(), to bypass the crash. It MUST disrupt the +		// flow of control because no caller expects LL_ERRS to return.  	LL_COMMON_API FatalFunction getFatalFunction();  		// Retrieve the previously-set FatalFunction @@ -147,14 +149,14 @@ namespace LLError  		virtual void recordMessage(LLError::ELevel, const std::string& message) = 0;  			// use the level for better display, not for filtering -        virtual bool enabled() { return true; } +		virtual bool enabled() { return true; }  		bool wantsTime();  		bool wantsTags();  		bool wantsLevel();  		bool wantsLocation();   		bool wantsFunctionName(); -        bool wantsMultiline(); +		bool wantsMultiline();  		void showTime(bool show);  		void showTags(bool show); @@ -165,15 +167,35 @@ namespace LLError  	protected:  		bool mWantsTime; -        bool mWantsTags; -        bool mWantsLevel; -        bool mWantsLocation; -        bool mWantsFunctionName; -        bool mWantsMultiline; +		bool mWantsTags; +		bool mWantsLevel; +		bool mWantsLocation; +		bool mWantsFunctionName; +		bool mWantsMultiline;  	};  	typedef boost::shared_ptr<Recorder> RecorderPtr; +    /** +     * Instantiate GenericRecorder with a callable(level, message) to get +     * control on every log message without having to code an explicit +     * Recorder subclass. +     */ +    template <typename CALLABLE> +    class GenericRecorder: public Recorder +    { +    public: +        GenericRecorder(const CALLABLE& callable): +            mCallable(callable) +        {} +        void recordMessage(LLError::ELevel level, const std::string& message) override +        { +            mCallable(level, message); +        } +    private: +        CALLABLE mCallable; +    }; +  	/**  	 * @NOTE: addRecorder() and removeRecorder() uses the boost::shared_ptr to allow for shared ownership  	 * while still ensuring that the allocated memory is eventually freed @@ -181,6 +203,19 @@ namespace LLError  	LL_COMMON_API void addRecorder(RecorderPtr);  	LL_COMMON_API void removeRecorder(RecorderPtr);  		// each error message is passed to each recorder via recordMessage() +	/** +	 * Call addGenericRecorder() with a callable(level, message) to get +	 * control on every log message without having to code an explicit +	 * Recorder subclass. Save the returned RecorderPtr if you later want to +	 * call removeRecorder(). +	 */ +	template <typename CALLABLE> +	RecorderPtr addGenericRecorder(const CALLABLE& callable) +	{ +		RecorderPtr ptr{ new GenericRecorder<CALLABLE>(callable) }; +		addRecorder(ptr); +		return ptr; +	}  	LL_COMMON_API void logToFile(const std::string& filename);  	LL_COMMON_API void logToStderr(); diff --git a/indra/llcommon/llleap.cpp b/indra/llcommon/llleap.cpp index cf8f8cc6a5..e8ea0ab398 100644 --- a/indra/llcommon/llleap.cpp +++ b/indra/llcommon/llleap.cpp @@ -59,7 +59,6 @@ public:          // pump name -- so it should NOT need tweaking for uniqueness.          mReplyPump(LLUUID::generateNewID().asString()),          mExpect(0), -        mPrevFatalFunction(LLError::getFatalFunction()),          // Instantiate a distinct LLLeapListener for this plugin. (Every          // plugin will want its own collection of managed listeners, etc.)          // Pass it a callback to our connect() method, so it can send events @@ -146,7 +145,9 @@ public:              .listen("LLLeap", boost::bind(&LLLeapImpl::rstderr, this, _1));          // For our lifespan, intercept any LL_ERRS so we can notify plugin -        LLError::setFatalFunction(boost::bind(&LLLeapImpl::fatalFunction, this, _1)); +        mRecorder = LLError::addGenericRecorder( +            [this](LLError::ELevel level, const std::string& message) +            { onError(level, message); });          // Send child a preliminary event reporting our own reply-pump name --          // which would otherwise be pretty tricky to guess! @@ -162,8 +163,7 @@ public:      virtual ~LLLeapImpl()      {          LL_DEBUGS("LLLeap") << "destroying LLLeap(\"" << mDesc << "\")" << LL_ENDL; -        // Restore original FatalFunction -        LLError::setFatalFunction(mPrevFatalFunction); +        LLError::removeRecorder(mRecorder);      }      // Listener for failed launch attempt @@ -377,28 +377,28 @@ public:          return false;      } -    void fatalFunction(const std::string& error) +    void onError(LLError::ELevel level, const std::string& error)      { -        // Notify plugin -        LLSD event; -        event["type"] = "error"; -        event["error"] = error; -        mReplyPump.post(event); - -        // All the above really accomplished was to buffer the serialized -        // event in our WritePipe. Have to pump mainloop a couple times to -        // really write it out there... but time out in case we can't write. -        LLProcess::WritePipe& childin(mChild->getWritePipe(LLProcess::STDIN)); -        LLEventPump& mainloop(LLEventPumps::instance().obtain("mainloop")); -        LLSD nop; -        F64 until = (LLTimer::getElapsedSeconds() + 2).value(); -        while (childin.size() && LLTimer::getElapsedSeconds() < until) +        if (level == LLError::LEVEL_ERROR)          { -            mainloop.post(nop); +            // Notify plugin +            LLSD event; +            event["type"] = "error"; +            event["error"] = error; +            mReplyPump.post(event); + +            // All the above really accomplished was to buffer the serialized +            // event in our WritePipe. Have to pump mainloop a couple times to +            // really write it out there... but time out in case we can't write. +            LLProcess::WritePipe& childin(mChild->getWritePipe(LLProcess::STDIN)); +            LLEventPump& mainloop(LLEventPumps::instance().obtain("mainloop")); +            LLSD nop; +            F64 until = (LLTimer::getElapsedSeconds() + 2).value(); +            while (childin.size() && LLTimer::getElapsedSeconds() < until) +            { +                mainloop.post(nop); +            }          } - -        // forward the call to the previous FatalFunction -        mPrevFatalFunction(error);      }  private: @@ -421,7 +421,7 @@ private:          mStdinConnection, mStdoutConnection, mStdoutDataConnection, mStderrConnection;      boost::scoped_ptr<LLEventPump::Blocker> mBlocker;      LLProcess::ReadPipe::size_type mExpect; -    LLError::FatalFunction mPrevFatalFunction; +    LLError::RecorderPtr mRecorder;      boost::scoped_ptr<LLLeapListener> mListener;  }; diff --git a/indra/llcommon/llsingleton.cpp b/indra/llcommon/llsingleton.cpp index ad933154c2..6b1986d0e9 100644 --- a/indra/llcommon/llsingleton.cpp +++ b/indra/llcommon/llsingleton.cpp @@ -38,11 +38,6 @@  #include <sstream>  #include <stdexcept> -namespace { -void log(LLError::ELevel level, -         const char* p1, const char* p2, const char* p3, const char* p4); -} // anonymous namespace -  // Our master list of all LLSingletons is itself an LLSingleton. We used to  // store it in a function-local static, but that could get destroyed before  // the last of the LLSingletons -- and ~LLSingletonBase() definitely wants to @@ -218,8 +213,8 @@ void LLSingletonBase::pop_initializing()      if (list.empty())      { -        logerrs("Underflow in stack of currently-initializing LLSingletons at ", -                classname(this).c_str(), "::getInstance()"); +        logerrs({"Underflow in stack of currently-initializing LLSingletons at ", +                classname(this), "::getInstance()"});      }      // Now we know list.back() exists: capture it @@ -240,9 +235,9 @@ void LLSingletonBase::pop_initializing()      // Now validate the newly-popped LLSingleton.      if (back != this)      { -        logerrs("Push/pop mismatch in stack of currently-initializing LLSingletons: ", -                classname(this).c_str(), "::getInstance() trying to pop ", -                classname(back).c_str()); +        logerrs({"Push/pop mismatch in stack of currently-initializing LLSingletons: ", +                classname(this), "::getInstance() trying to pop ", +                classname(back)});      }      // log AFTER popping so logging singletons don't cry circularity @@ -331,15 +326,15 @@ void LLSingletonBase::capture_dependency()                  //                  // Example: LLNotifications singleton initializes default channels.                  // Channels register themselves with singleton once done. -                logdebugs("LLSingleton circularity: ", out.str().c_str(), -                    classname(this).c_str(), ""); +                logdebugs({"LLSingleton circularity: ", out.str(), +                          classname(this)});              }              else              {                  // Actual circularity with other singleton (or single singleton is used extensively).                  // Dependency can be unclear. -                logwarns("LLSingleton circularity: ", out.str().c_str(), -                    classname(this).c_str(), ""); +                logwarns({"LLSingleton circularity: ", out.str(), +                         classname(this)});              }          }          else @@ -352,8 +347,8 @@ void LLSingletonBase::capture_dependency()              if (current->mDepends.insert(this).second)              {                  // only log the FIRST time we hit this dependency! -                logdebugs(classname(current).c_str(), -                          " depends on ", classname(this).c_str()); +                logdebugs({classname(current), +                          " depends on ", classname(this)});              }          }      } @@ -401,7 +396,7 @@ LLSingletonBase::vec_t LLSingletonBase::dep_sort()  void LLSingletonBase::cleanup_()  { -    logdebugs("calling ", classname(this).c_str(), "::cleanupSingleton()"); +    logdebugs({"calling ", classname(this), "::cleanupSingleton()"});      try      {          cleanupSingleton(); @@ -427,23 +422,23 @@ void LLSingletonBase::deleteAll()              if (! sp->mDeleteSingleton)              {                  // This Should Not Happen... but carry on. -                logwarns(name.c_str(), "::mDeleteSingleton not initialized!"); +                logwarns({name, "::mDeleteSingleton not initialized!"});              }              else              {                  // properly initialized: call it. -                logdebugs("calling ", name.c_str(), "::deleteSingleton()"); +                logdebugs({"calling ", name, "::deleteSingleton()"});                  // From this point on, DO NOT DEREFERENCE sp!                  sp->mDeleteSingleton();              }          }          catch (const std::exception& e)          { -            logwarns("Exception in ", name.c_str(), "::deleteSingleton(): ", e.what()); +            logwarns({"Exception in ", name, "::deleteSingleton(): ", e.what()});          }          catch (...)          { -            logwarns("Unknown exception in ", name.c_str(), "::deleteSingleton()"); +            logwarns({"Unknown exception in ", name, "::deleteSingleton()"});          }      }  } @@ -451,49 +446,40 @@ void LLSingletonBase::deleteAll()  /*---------------------------- Logging helpers -----------------------------*/  namespace { -void log(LLError::ELevel level, -         const char* p1, const char* p2, const char* p3, const char* p4) +std::ostream& operator<<(std::ostream& out, const LLSingletonBase::string_params& args)  { -    LL_VLOGS(level, "LLSingleton") << p1 << p2 << p3 << p4 << LL_ENDL; +    // However many args there are in args, stream each of them to 'out'. +    for (auto arg : args) +    { +        out << arg; +    } +    return out;  }  } // anonymous namespace          //static -void LLSingletonBase::logwarns(const char* p1, const char* p2, const char* p3, const char* p4) +void LLSingletonBase::logwarns(const string_params& args)  { -    log(LLError::LEVEL_WARN, p1, p2, p3, p4); +    LL_WARNS("LLSingleton") << args << LL_ENDL;  }  //static -void LLSingletonBase::loginfos(const char* p1, const char* p2, const char* p3, const char* p4) +void LLSingletonBase::loginfos(const string_params& args)  { -    log(LLError::LEVEL_INFO, p1, p2, p3, p4); +    LL_INFOS("LLSingleton") << args << LL_ENDL;  }  //static -void LLSingletonBase::logdebugs(const char* p1, const char* p2, const char* p3, const char* p4) +void LLSingletonBase::logdebugs(const string_params& args)  { -    log(LLError::LEVEL_DEBUG, p1, p2, p3, p4); +    LL_DEBUGS("LLSingleton") << args << LL_ENDL;  }  //static -void LLSingletonBase::logerrs(const char* p1, const char* p2, const char* p3, const char* p4) +void LLSingletonBase::logerrs(const string_params& args)  { -    log(LLError::LEVEL_ERROR, p1, p2, p3, p4); -    // The other important side effect of LL_ERRS() is -    // https://www.youtube.com/watch?v=OMG7paGJqhQ (emphasis on OMG) -    std::ostringstream out; -    out << p1 << p2 << p3 << p4; -    auto crash = LLError::getFatalFunction(); -    if (crash) -    { -        crash(out.str()); -    } -    else -    { -        LLError::crashAndLoop(out.str()); -    } +    LL_ERRS("LLSingleton") << args << LL_ENDL;  }  std::string LLSingletonBase::demangle(const char* mangled) diff --git a/indra/llcommon/llsingleton.h b/indra/llcommon/llsingleton.h index 30a5b21cf8..7c81d65a8b 100644 --- a/indra/llcommon/llsingleton.h +++ b/indra/llcommon/llsingleton.h @@ -27,9 +27,10 @@  #include <boost/noncopyable.hpp>  #include <boost/unordered_set.hpp> +#include <initializer_list>  #include <list> -#include <vector>  #include <typeinfo> +#include <vector>  #include "mutex.h"  #include "lockstatic.h"  #include "llthread.h"               // on_main_thread() @@ -111,14 +112,13 @@ protected:      void capture_dependency();      // delegate logging calls to llsingleton.cpp -    static void logerrs(const char* p1, const char* p2="", -                        const char* p3="", const char* p4=""); -    static void logwarns(const char* p1, const char* p2="", -                         const char* p3="", const char* p4=""); -    static void loginfos(const char* p1, const char* p2="", -                         const char* p3="", const char* p4=""); -    static void logdebugs(const char* p1, const char* p2="", -                          const char* p3="", const char* p4=""); +public: +    typedef std::initializer_list<const std::string> string_params; +protected: +    static void logerrs  (const string_params&); +    static void logwarns (const string_params&); +    static void loginfos (const string_params&); +    static void logdebugs(const string_params&);      static std::string demangle(const char* mangled);      // these classname() declarations restate template functions declared in      // llerror.h because we avoid #including that here @@ -327,8 +327,8 @@ private:              // init stack to its previous size BEFORE logging so log-machinery              // LLSingletons don't record a dependency on DERIVED_TYPE!              LLSingleton_manage_master<DERIVED_TYPE>().reset_initializing(prev_size); -            logwarns("Error constructing ", classname<DERIVED_TYPE>().c_str(), -                     ": ", err.what()); +            logwarns({"Error constructing ", classname<DERIVED_TYPE>(), +                     ": ", err.what()});              // There isn't a separate EInitState value meaning "we attempted              // to construct this LLSingleton subclass but could not," so use              // DELETED. That seems slightly more appropriate than UNINITIALIZED. @@ -356,8 +356,8 @@ private:              // BEFORE logging, so log-machinery LLSingletons don't record a              // dependency on DERIVED_TYPE!              pop_initializing(lk->mInstance); -            logwarns("Error in ", classname<DERIVED_TYPE>().c_str(), -                     "::initSingleton(): ", err.what()); +            logwarns({"Error in ", classname<DERIVED_TYPE>(), +                     "::initSingleton(): ", err.what()});              // Get rid of the instance entirely. This call depends on our              // recursive_mutex. We could have a deleteSingleton(LockStatic&)              // overload and pass lk, but we don't strictly need it. @@ -506,9 +506,9 @@ public:              case CONSTRUCTING:                  // here if DERIVED_TYPE's constructor (directly or indirectly)                  // calls DERIVED_TYPE::getInstance() -                logerrs("Tried to access singleton ", -                        classname<DERIVED_TYPE>().c_str(), -                        " from singleton constructor!"); +                logerrs({"Tried to access singleton ", +                        classname<DERIVED_TYPE>(), +                        " from singleton constructor!"});                  return nullptr;              case INITIALIZING: @@ -523,9 +523,9 @@ public:              case DELETED:                  // called after deleteSingleton() -                logwarns("Trying to access deleted singleton ", -                         classname<DERIVED_TYPE>().c_str(), -                         " -- creating new instance"); +                logwarns({"Trying to access deleted singleton ", +                         classname<DERIVED_TYPE>(), +                         " -- creating new instance"});                  // fall through              case UNINITIALIZED:              case QUEUED: @@ -552,8 +552,8 @@ public:          } // unlock 'lk'          // Per the comment block above, dispatch to the main thread. -        loginfos(classname<DERIVED_TYPE>().c_str(), -                 "::getInstance() dispatching to main thread"); +        loginfos({classname<DERIVED_TYPE>(), +                 "::getInstance() dispatching to main thread"});          auto instance = LLMainThreadTask::dispatch(              [](){                  // VERY IMPORTANT to call getInstance() on the main thread, @@ -563,16 +563,16 @@ public:                  // the main thread processes them, only the FIRST such request                  // actually constructs the instance -- every subsequent one                  // simply returns the existing instance. -                loginfos(classname<DERIVED_TYPE>().c_str(), -                         "::getInstance() on main thread"); +                loginfos({classname<DERIVED_TYPE>(), +                         "::getInstance() on main thread"});                  return getInstance();              });          // record the dependency chain tracked on THIS thread, not the main          // thread (consider a getInstance() overload with a tag param that          // suppresses dep tracking when dispatched to the main thread)          capture_dependency(instance); -        loginfos(classname<DERIVED_TYPE>().c_str(), -                 "::getInstance() returning on requesting thread"); +        loginfos({classname<DERIVED_TYPE>(), +                 "::getInstance() returning on requesting thread"});          return instance;      } @@ -641,16 +641,16 @@ private:          // For organizational purposes this function shouldn't be called twice          if (lk->mInitState != super::UNINITIALIZED)          { -            super::logerrs("Tried to initialize singleton ", -                           super::template classname<DERIVED_TYPE>().c_str(), -                           " twice!"); +            super::logerrs({"Tried to initialize singleton ", +                           super::template classname<DERIVED_TYPE>(), +                           " twice!"});              return nullptr;          }          else if (on_main_thread())          {              // on the main thread, simply construct instance while holding lock -            super::logdebugs(super::template classname<DERIVED_TYPE>().c_str(), -                             "::initParamSingleton()"); +            super::logdebugs({super::template classname<DERIVED_TYPE>(), +                             "::initParamSingleton()"});              super::constructSingleton(lk, std::forward<Args>(args)...);              return lk->mInstance;          } @@ -662,8 +662,8 @@ private:              lk->mInitState = super::QUEUED;              // very important to unlock here so main thread can actually process              lk.unlock(); -            super::loginfos(super::template classname<DERIVED_TYPE>().c_str(), -                            "::initParamSingleton() dispatching to main thread"); +            super::loginfos({super::template classname<DERIVED_TYPE>(), +                            "::initParamSingleton() dispatching to main thread"});              // Normally it would be the height of folly to reference-bind              // 'args' into a lambda to be executed on some other thread! By              // the time that thread executed the lambda, the references would @@ -674,12 +674,12 @@ private:              // references.              auto instance = LLMainThreadTask::dispatch(                  [&](){ -                    super::loginfos(super::template classname<DERIVED_TYPE>().c_str(), -                                    "::initParamSingleton() on main thread"); +                    super::loginfos({super::template classname<DERIVED_TYPE>(), +                                    "::initParamSingleton() on main thread"});                      return initParamSingleton_(std::forward<Args>(args)...);                  }); -            super::loginfos(super::template classname<DERIVED_TYPE>().c_str(), -                            "::initParamSingleton() returning on requesting thread"); +            super::loginfos({super::template classname<DERIVED_TYPE>(), +                            "::initParamSingleton() returning on requesting thread"});              return instance;          }      } @@ -707,14 +707,14 @@ public:          {          case super::UNINITIALIZED:          case super::QUEUED: -            super::logerrs("Uninitialized param singleton ", -                           super::template classname<DERIVED_TYPE>().c_str()); +            super::logerrs({"Uninitialized param singleton ", +                           super::template classname<DERIVED_TYPE>()});              break;          case super::CONSTRUCTING: -            super::logerrs("Tried to access param singleton ", -                           super::template classname<DERIVED_TYPE>().c_str(), -                           " from singleton constructor!"); +            super::logerrs({"Tried to access param singleton ", +                           super::template classname<DERIVED_TYPE>(), +                           " from singleton constructor!"});              break;          case super::INITIALIZING: @@ -726,8 +726,8 @@ public:              return lk->mInstance;          case super::DELETED: -            super::logerrs("Trying to access deleted param singleton ", -                           super::template classname<DERIVED_TYPE>().c_str()); +            super::logerrs({"Trying to access deleted param singleton ", +                           super::template classname<DERIVED_TYPE>()});              break;          } diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp index 98905f3b71..6d531d842d 100644 --- a/indra/llcommon/llthread.cpp +++ b/indra/llcommon/llthread.cpp @@ -354,8 +354,9 @@ void LLThread::setQuitting()      {          mStatus = QUITTING;      } +    // It's only safe to remove mRunCondition if all locked threads were notified +    mRunCondition->broadcast();      mDataLock->unlock(); -    wake();  }  // static diff --git a/indra/llcommon/lluri.cpp b/indra/llcommon/lluri.cpp index 9942bc0cf8..22711a83d2 100644 --- a/indra/llcommon/lluri.cpp +++ b/indra/llcommon/lluri.cpp @@ -276,7 +276,7 @@ std::string LLURI::escapePathAndData(const std::string &str)              std::string fragment;              size_t fragment_pos = str.find('#'); -            if (fragment_pos != std::string::npos) +            if ((fragment_pos != std::string::npos) && (fragment_pos > delim_pos))              {                  query = str.substr(path_size, fragment_pos - path_size);                  fragment = str.substr(fragment_pos); diff --git a/indra/llcommon/tests/llerror_test.cpp b/indra/llcommon/tests/llerror_test.cpp index 8e1f4c14ac..148c18aabe 100644 --- a/indra/llcommon/tests/llerror_test.cpp +++ b/indra/llcommon/tests/llerror_test.cpp @@ -26,6 +26,7 @@   */  #include <vector> +#include <stdexcept>  #include "linden_common.h" @@ -69,21 +70,41 @@ namespace  namespace  { -	static bool fatalWasCalled; -	void fatalCall(const std::string&) { fatalWasCalled = true; } +	static bool fatalWasCalled = false; +    struct FatalWasCalled: public std::runtime_error +    { +        FatalWasCalled(const std::string& what): std::runtime_error(what) {} +    }; +    void fatalCall(const std::string& msg) { throw FatalWasCalled(msg); }  } +// Because we use LLError::setFatalFunction(fatalCall), any LL_ERRS call we +// issue will throw FatalWasCalled. But we want the test program to continue. +// So instead of writing: +// LL_ERRS("tag") << "some message" << LL_ENDL; +// write: +// CATCH(LL_ERRS("tag"), "some message"); +#define CATCH(logcall, expr)                    \ +    try                                         \ +    {                                           \ +        logcall << expr << LL_ENDL;             \ +    }                                           \ +    catch (const FatalWasCalled&)               \ +    {                                           \ +        fatalWasCalled = true;                  \ +    } +  namespace tut  {  	class TestRecorder : public LLError::Recorder  	{  	public:  		TestRecorder() -            { -                showTime(false); -            } +			{ +				showTime(false); +			}  		virtual ~TestRecorder() -            {} +			{}  		virtual void recordMessage(LLError::ELevel level,  						   const std::string& message) @@ -252,7 +273,7 @@ namespace  		LL_DEBUGS("WriteTag","AnotherTag") << "one" << LL_ENDL;  		LL_INFOS("WriteTag") << "two" << LL_ENDL;  		LL_WARNS("WriteTag") << "three" << LL_ENDL; -		LL_ERRS("WriteTag") << "four" << LL_ENDL; +		CATCH(LL_ERRS("WriteTag"), "four");  	}  }; @@ -380,7 +401,7 @@ namespace  	std::string errorReturningLocation()  	{ -		LL_ERRS() << "die" << LL_ENDL;	int this_line = __LINE__; +		int this_line = __LINE__;	CATCH(LL_ERRS(), "die");  		return locationString(this_line);  	}  } @@ -701,7 +722,7 @@ public:  	static void doDebug()	{ LL_DEBUGS() << "add dice" << LL_ENDL; }  	static void doInfo()	{ LL_INFOS()  << "any idea" << LL_ENDL; }  	static void doWarn()	{ LL_WARNS()  << "aim west" << LL_ENDL; } -	static void doError()	{ LL_ERRS()   << "ate eels" << LL_ENDL; } +	static void doError()	{ CATCH(LL_ERRS(), "ate eels"); }  	static void doAll() { doDebug(); doInfo(); doWarn(); doError(); }  }; @@ -712,7 +733,7 @@ public:  	static void doDebug()	{ LL_DEBUGS() << "bed down" << LL_ENDL; }  	static void doInfo()	{ LL_INFOS()  << "buy iron" << LL_ENDL; }  	static void doWarn()	{ LL_WARNS()  << "bad word" << LL_ENDL; } -	static void doError()	{ LL_ERRS()   << "big easy" << LL_ENDL; } +	static void doError()	{ CATCH(LL_ERRS(), "big easy"); }  	static void doAll() { doDebug(); doInfo(); doWarn(); doError(); }  }; @@ -874,13 +895,10 @@ namespace tut  namespace  {      std::string writeTagWithSpaceReturningLocation() -	{ -        LL_DEBUGS("Write Tag") << "not allowed" << LL_ENDL;	int this_line = __LINE__; -         -        std::ostringstream location; -        location << LLError::abbreviateFile(__FILE__).c_str() << "(" << this_line << ")"; -        return location.str(); -	} +    { +        int this_line = __LINE__; CATCH(LL_DEBUGS("Write Tag"), "not allowed"); +        return locationString(this_line); +    }  };  namespace tut @@ -894,9 +912,9 @@ namespace tut          std::string location = writeTagWithSpaceReturningLocation();          std::string expected = "Space is not allowed in a log tag at " + location; -		ensure_message_field_equals(0, LEVEL_FIELD, "ERROR"); -		ensure_message_field_equals(0, MSG_FIELD, expected); -		ensure("fatal callback called", fatalWasCalled); +        ensure_message_field_equals(0, LEVEL_FIELD, "ERROR"); +        ensure_message_field_equals(0, MSG_FIELD, expected); +        ensure("fatal callback called", fatalWasCalled);      }  } diff --git a/indra/llcommon/tests/wrapllerrs.h b/indra/llcommon/tests/wrapllerrs.h index b07d5afbd8..3779fb41bc 100644 --- a/indra/llcommon/tests/wrapllerrs.h +++ b/indra/llcommon/tests/wrapllerrs.h @@ -44,10 +44,6 @@  #include <list>  #include <string> -// statically reference the function in test.cpp... it's short, we could -// replicate, but better to reuse -extern void wouldHaveCrashed(const std::string& message); -  struct WrapLLErrs  {      WrapLLErrs(): @@ -59,7 +55,8 @@ struct WrapLLErrs          mPriorFatal(LLError::getFatalFunction())      {          // Make LL_ERRS call our own operator() method -        LLError::setFatalFunction(boost::bind(&WrapLLErrs::operator(), this, _1)); +        LLError::setFatalFunction( +            [this](const std::string& message){ (*this)(message); });      }      ~WrapLLErrs() @@ -199,11 +196,13 @@ public:          // with that output. If it turns out that saveAndResetSettings() has          // some bad effect, give up and just let the DEBUG level log messages          // display. -		: boost::noncopyable(), +        : boost::noncopyable(), +        mFatalFunction(LLError::getFatalFunction()),          mOldSettings(LLError::saveAndResetSettings()), -		mRecorder(new CaptureLogRecorder()) +        mRecorder(new CaptureLogRecorder())      { -        LLError::setFatalFunction(wouldHaveCrashed); +        // reinstate the FatalFunction we just reset +        LLError::setFatalFunction(mFatalFunction);          LLError::setDefaultLevel(level);          LLError::addRecorder(mRecorder);      } @@ -219,17 +218,18 @@ public:      /// for the sought string.      std::string messageWith(const std::string& search, bool required=true)      { -		return boost::dynamic_pointer_cast<CaptureLogRecorder>(mRecorder)->messageWith(search, required); +        return boost::dynamic_pointer_cast<CaptureLogRecorder>(mRecorder)->messageWith(search, required);      }      std::ostream& streamto(std::ostream& out) const      { -		return boost::dynamic_pointer_cast<CaptureLogRecorder>(mRecorder)->streamto(out); +        return boost::dynamic_pointer_cast<CaptureLogRecorder>(mRecorder)->streamto(out);      }  private: +    LLError::FatalFunction mFatalFunction;      LLError::SettingsStoragePtr mOldSettings; -	LLError::RecorderPtr mRecorder; +    LLError::RecorderPtr mRecorder;  };  #endif /* ! defined(LL_WRAPLLERRS_H) */ diff --git a/indra/llcorehttp/CMakeLists.txt b/indra/llcorehttp/CMakeLists.txt index 240ea2da83..8bb6a657b1 100644 --- a/indra/llcorehttp/CMakeLists.txt +++ b/indra/llcorehttp/CMakeLists.txt @@ -13,6 +13,7 @@ include(LLAddBuildTest)  include(LLMessage)  include(LLCommon)  include(Tut) +include(bugsplat)  include_directories (${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/indra/llcorehttp/_httpreplyqueue.cpp b/indra/llcorehttp/_httpreplyqueue.cpp index 2b138f3ad5..229bfdbe07 100644 --- a/indra/llcorehttp/_httpreplyqueue.cpp +++ b/indra/llcorehttp/_httpreplyqueue.cpp @@ -56,7 +56,6 @@ void HttpReplyQueue::addOp(const HttpReplyQueue::opPtr_t &op)  		mQueue.push_back(op);  	} -	mQueueCV.notify_all();  } diff --git a/indra/llcorehttp/_httpreplyqueue.h b/indra/llcorehttp/_httpreplyqueue.h index 928ee10a83..33e205c1c9 100644 --- a/indra/llcorehttp/_httpreplyqueue.h +++ b/indra/llcorehttp/_httpreplyqueue.h @@ -98,7 +98,6 @@ protected:  	OpContainer							mQueue;  	LLCoreInt::HttpMutex				mQueueMutex; -	LLCoreInt::HttpConditionVariable	mQueueCV;  }; // end class HttpReplyQueue diff --git a/indra/llcorehttp/_httprequestqueue.cpp b/indra/llcorehttp/_httprequestqueue.cpp index c6f4ad789f..ad72bdcce6 100644 --- a/indra/llcorehttp/_httprequestqueue.cpp +++ b/indra/llcorehttp/_httprequestqueue.cpp @@ -142,13 +142,19 @@ void HttpRequestQueue::wakeAll()  } -void HttpRequestQueue::stopQueue() +bool HttpRequestQueue::stopQueue()  {  	{  		HttpScopedLock lock(mQueueMutex); -		mQueueStopped = true; -		wakeAll(); +        if (!mQueueStopped) +        { +            mQueueStopped = true; +            wakeAll(); +            return true; +        } +        wakeAll(); +        return false;  	}  } diff --git a/indra/llcorehttp/_httprequestqueue.h b/indra/llcorehttp/_httprequestqueue.h index 3c3d134b07..f0296f30e3 100644 --- a/indra/llcorehttp/_httprequestqueue.h +++ b/indra/llcorehttp/_httprequestqueue.h @@ -124,7 +124,7 @@ public:  	/// them on their way.  	///  	/// Threading:  callable by any thread. -	void stopQueue(); +	bool stopQueue();  protected:  	static HttpRequestQueue *			sInstance; diff --git a/indra/llcorehttp/_httpservice.cpp b/indra/llcorehttp/_httpservice.cpp index 34268d94f6..56f52f1b09 100644 --- a/indra/llcorehttp/_httpservice.cpp +++ b/indra/llcorehttp/_httpservice.cpp @@ -87,7 +87,11 @@ HttpService::~HttpService()  		// is a bit tricky.  		if (mRequestQueue)  		{ -			mRequestQueue->stopQueue(); +            if (mRequestQueue->stopQueue()) +            { +                // Give mRequestQueue a chance to finish +                ms_sleep(10); +            }  		}  		if (mThread) diff --git a/indra/llcorehttp/httpoptions.cpp b/indra/llcorehttp/httpoptions.cpp index df5aa52fa9..c6365e5091 100644 --- a/indra/llcorehttp/httpoptions.cpp +++ b/indra/llcorehttp/httpoptions.cpp @@ -32,6 +32,7 @@  namespace LLCore  { +    bool HttpOptions::sDefaultVerifyPeer = false;  HttpOptions::HttpOptions() :      mWantHeaders(false), @@ -43,7 +44,7 @@ HttpOptions::HttpOptions() :      mMaxRetryBackoff(HTTP_RETRY_BACKOFF_MAX_DEFAULT),      mUseRetryAfter(HTTP_USE_RETRY_AFTER_DEFAULT),      mFollowRedirects(true), -    mVerifyPeer(false), +    mVerifyPeer(sDefaultVerifyPeer),      mVerifyHost(false),      mDNSCacheTimeout(-1L),      mNoBody(false) @@ -122,7 +123,15 @@ void HttpOptions::setHeadersOnly(bool nobody)  {      mNoBody = nobody;      if (mNoBody) +    {          setWantHeaders(true); +        setSSLVerifyPeer(false); +    } +} + +void HttpOptions::setDefaultSSLVerifyPeer(bool verify) +{ +    sDefaultVerifyPeer = verify;  }  }   // end namespace LLCore diff --git a/indra/llcorehttp/httpoptions.h b/indra/llcorehttp/httpoptions.h index 8a6de61b04..41f71896b0 100644 --- a/indra/llcorehttp/httpoptions.h +++ b/indra/llcorehttp/httpoptions.h @@ -143,7 +143,7 @@ public:      /// Instructs the LLCore::HTTPRequest to verify that the exchanged security      /// certificate is authentic.  -    /// Default: false +    /// Default: sDefaultVerifyPeer      void				setSSLVerifyPeer(bool verify);  	bool				getSSLVerifyPeer() const  	{ @@ -177,6 +177,13 @@ public:      {          return mNoBody;      } + +    /// Sets default behavior for verifying that the name in the  +    /// security certificate matches the name of the host contacted. +    /// Defaults false if not set, but should be set according to +    /// viewer's initialization options and command argunments, see +    /// NoVerifySSLCert +    static void         setDefaultSSLVerifyPeer(bool verify);  protected:  	bool				mWantHeaders; @@ -192,6 +199,8 @@ protected:  	bool        		mVerifyHost;  	int					mDNSCacheTimeout;      bool                mNoBody; + +    static bool         sDefaultVerifyPeer;  }; // end class HttpOptions diff --git a/indra/llcrashlogger/README.txt b/indra/llcrashlogger/README.txt new file mode 100644 index 0000000000..6932a8d9c3 --- /dev/null +++ b/indra/llcrashlogger/README.txt @@ -0,0 +1,3 @@ +This component is no longer used in Linden Lab builds. +Change requests to support continued use by open source +builds are welcome. diff --git a/indra/llcrashlogger/llcrashlogger.cpp b/indra/llcrashlogger/llcrashlogger.cpp index 62fcdaf545..e02f3a6306 100644 --- a/indra/llcrashlogger/llcrashlogger.cpp +++ b/indra/llcrashlogger/llcrashlogger.cpp @@ -411,6 +411,7 @@ bool LLCrashLogger::runCrashLogPost(std::string host, LLSD data, std::string msg      LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);      httpOpts->setTimeout(timeout); +    httpOpts->setSSLVerifyPeer(false);  	for(int i = 0; i < retries; ++i)  	{ diff --git a/indra/llimage/CMakeLists.txt b/indra/llimage/CMakeLists.txt index 293ada7548..28b8e8c06d 100644 --- a/indra/llimage/CMakeLists.txt +++ b/indra/llimage/CMakeLists.txt @@ -11,6 +11,7 @@ include(LLKDU)  include(LLImageJ2COJ)  include(ZLIB)  include(LLAddBuildTest) +include(bugsplat)  include(Tut)  include_directories( diff --git a/indra/llinventory/lllandmark.cpp b/indra/llinventory/lllandmark.cpp index 4c6075d6b5..bd7ab3c2c8 100644 --- a/indra/llinventory/lllandmark.cpp +++ b/indra/llinventory/lllandmark.cpp @@ -103,60 +103,104 @@ LLVector3 LLLandmark::getRegionPos() const  // static -LLLandmark* LLLandmark::constructFromString(const char *buffer) +LLLandmark* LLLandmark::constructFromString(const char *buffer, const S32 buffer_size)  { -	const char* cur = buffer;  	S32 chars_read = 0; +	S32 chars_read_total = 0;  	S32 count = 0;  	U32 version = 0; +    bool bad_block = false; +    LLLandmark* result = NULL; +  	// read version  -	count = sscanf( cur, "Landmark version %u\n%n", &version, &chars_read ); -	if(count != 1) -	{ -		goto error; -	} +	count = sscanf( buffer, "Landmark version %u\n%n", &version, &chars_read ); +    chars_read_total += chars_read; -	if(version == 1) -	{ -		LLVector3d pos; -		cur += chars_read; -		// read position -		count = sscanf( cur, "position %lf %lf %lf\n%n", pos.mdV+VX, pos.mdV+VY, pos.mdV+VZ, &chars_read ); -		if( count != 3 ) -		{ -			goto error; -		} -		cur += chars_read; -		// LL_INFOS() << "Landmark read: " << pos << LL_ENDL; -		 -		return new LLLandmark(pos); -	} -	else if(version == 2) -	{ -		// *NOTE: Changing the buffer size will require changing the -		// scanf call below. -		char region_id_str[MAX_STRING];	/* Flawfinder: ignore */ -		LLVector3 pos; -		cur += chars_read; -		count = sscanf(	/* Flawfinder: ignore */ -			cur, -			"region_id %254s\n%n", -			region_id_str, &chars_read); -		if(count != 1) goto error; -		cur += chars_read; -		count = sscanf(cur, "local_pos %f %f %f\n%n", pos.mV+VX, pos.mV+VY, pos.mV+VZ, &chars_read); -		if(count != 3) goto error; -		cur += chars_read; -		LLLandmark* lm = new LLLandmark; -		lm->mRegionID.set(region_id_str); -		lm->mRegionPos = pos; -		return lm; -	} +    if (count != 1 +        || chars_read_total >= buffer_size) +    { +        bad_block = true; +    } + +    if (!bad_block) +    { +        switch (version) +        { +            case 1: +            { +                LLVector3d pos; +                // read position +                count = sscanf(buffer + chars_read_total, "position %lf %lf %lf\n%n", pos.mdV + VX, pos.mdV + VY, pos.mdV + VZ, &chars_read); +                if (count != 3) +                { +                    bad_block = true; +                } +                else +                { +                    LL_DEBUGS("Landmark") << "Landmark read: " << pos << LL_ENDL; +                    result = new LLLandmark(pos); +                } +                break; +            } +            case 2: +            { +                // *NOTE: Changing the buffer size will require changing the +                // scanf call below. +                char region_id_str[MAX_STRING]; +                LLVector3 pos; +                LLUUID region_id; +                count = sscanf( buffer + chars_read_total, +                                "region_id %254s\n%n", +                                region_id_str, +                                &chars_read); +                chars_read_total += chars_read; + +                if (count != 1 +                    || chars_read_total >= buffer_size +                    || !LLUUID::validate(region_id_str)) +                { +                    bad_block = true; +                } + +                if (!bad_block) +                { +                    region_id.set(region_id_str); +                    if (region_id.isNull()) +                    { +                        bad_block = true; +                    } +                } + +                if (!bad_block) +                { +                    count = sscanf(buffer + chars_read_total, "local_pos %f %f %f\n%n", pos.mV + VX, pos.mV + VY, pos.mV + VZ, &chars_read); +                    if (count != 3) +                    { +                        bad_block = true; +                    } +                    else +                    { +                        result = new LLLandmark; +                        result->mRegionID = region_id; +                        result->mRegionPos = pos; +                    } +                } +                break; +            } +            default: +            { +                LL_INFOS("Landmark") << "Encountered Unknown landmark version " << version << LL_ENDL; +                break; +            } +        } +    } - error: -	LL_INFOS() << "Bad Landmark Asset: bad _DATA_ block." << LL_ENDL; -	return NULL; +    if (bad_block) +    { +        LL_INFOS("Landmark") << "Bad Landmark Asset: bad _DATA_ block." << LL_ENDL; +    } +    return result;  } @@ -176,7 +220,7 @@ void LLLandmark::requestRegionHandle(  	if(region_id.isNull())  	{  		// don't bother with checking - it's 0. -		LL_DEBUGS() << "requestRegionHandle: null" << LL_ENDL; +		LL_DEBUGS("Landmark") << "requestRegionHandle: null" << LL_ENDL;  		if(callback)  		{  			const U64 U64_ZERO = 0; @@ -187,7 +231,7 @@ void LLLandmark::requestRegionHandle(  	{  		if(region_id == mLocalRegion.first)  		{ -			LL_DEBUGS() << "requestRegionHandle: local" << LL_ENDL; +			LL_DEBUGS("Landmark") << "requestRegionHandle: local" << LL_ENDL;  			if(callback)  			{  				callback(region_id, mLocalRegion.second); @@ -198,13 +242,13 @@ void LLLandmark::requestRegionHandle(  			region_map_t::iterator it = mRegions.find(region_id);  			if(it == mRegions.end())  			{ -				LL_DEBUGS() << "requestRegionHandle: upstream" << LL_ENDL; +				LL_DEBUGS("Landmark") << "requestRegionHandle: upstream" << LL_ENDL;  				if(callback)  				{  					region_callback_map_t::value_type vt(region_id, callback);  					sRegionCallbackMap.insert(vt);  				} -				LL_DEBUGS() << "Landmark requesting information about: " +				LL_DEBUGS("Landmark") << "Landmark requesting information about: "  						 << region_id << LL_ENDL;  				msg->newMessage("RegionHandleRequest");  				msg->nextBlock("RequestBlock"); @@ -214,7 +258,7 @@ void LLLandmark::requestRegionHandle(  			else if(callback)  			{  				// we have the answer locally - just call the callack. -				LL_DEBUGS() << "requestRegionHandle: ready" << LL_ENDL; +				LL_DEBUGS("Landmark") << "requestRegionHandle: ready" << LL_ENDL;  				callback(region_id, (*it).second.mRegionHandle);  			}  		} diff --git a/indra/llinventory/lllandmark.h b/indra/llinventory/lllandmark.h index 92923ea6fb..be34113a90 100644 --- a/indra/llinventory/lllandmark.h +++ b/indra/llinventory/lllandmark.h @@ -60,7 +60,7 @@ public:  	// constructs a new LLLandmark from a string  	// return NULL if there's an error -	static LLLandmark* constructFromString(const char *buffer); +	static LLLandmark* constructFromString(const char *buffer, const S32 buffer_size);  	// register callbacks that this class handles  	static void registerCallbacks(LLMessageSystem* msg); diff --git a/indra/llinventory/llparcel.h b/indra/llinventory/llparcel.h index 3b39aeb56b..5d08c1f4c6 100644 --- a/indra/llinventory/llparcel.h +++ b/indra/llinventory/llparcel.h @@ -295,7 +295,6 @@ public:  	void	setAllowTerraform(BOOL b){setParcelFlag(PF_ALLOW_TERRAFORM, b); }  	void	setAllowDamage(BOOL b)	{ setParcelFlag(PF_ALLOW_DAMAGE, b); }  	void	setAllowFly(BOOL b)		{ setParcelFlag(PF_ALLOW_FLY, b); } -	void	setAllowLandmark(BOOL b){ setParcelFlag(PF_ALLOW_LANDMARK, b); }  	void	setAllowGroupScripts(BOOL b)	{ setParcelFlag(PF_ALLOW_GROUP_SCRIPTS, b); }  	void	setAllowOtherScripts(BOOL b)	{ setParcelFlag(PF_ALLOW_OTHER_SCRIPTS, b); }  	void	setAllowDeedToGroup(BOOL b) { setParcelFlag(PF_ALLOW_DEED_TO_GROUP, b); } @@ -476,11 +475,6 @@ public:  	BOOL	getAllowFly() const  					{ return (mParcelFlags & PF_ALLOW_FLY) ? TRUE : FALSE; } -	// Remove permission restrictions for creating landmarks. -	// We should eventually remove this flag completely. -	BOOL	getAllowLandmark() const -					{ return TRUE; } -  	BOOL	getAllowGroupScripts() const  					{ return (mParcelFlags & PF_ALLOW_GROUP_SCRIPTS) ? TRUE : FALSE; } diff --git a/indra/llinventory/llparcelflags.h b/indra/llinventory/llparcelflags.h index 25b27a281a..4cffa83cc1 100644 --- a/indra/llinventory/llparcelflags.h +++ b/indra/llinventory/llparcelflags.h @@ -33,7 +33,7 @@ const U32 PF_ALLOW_FLY			= 1 << 0;// Can start flying  const U32 PF_ALLOW_OTHER_SCRIPTS= 1 << 1;// Scripts by others can run.  const U32 PF_FOR_SALE			= 1 << 2;// Can buy this land  const U32 PF_FOR_SALE_OBJECTS	= 1 << 7;// Can buy all objects on this land -const U32 PF_ALLOW_LANDMARK		= 1 << 3; +const U32 PF_ALLOW_LANDMARK		= 1 << 3;// Always true/deprecated  const U32 PF_ALLOW_TERRAFORM	= 1 << 4;  const U32 PF_ALLOW_DAMAGE		= 1 << 5;  const U32 PF_CREATE_OBJECTS		= 1 << 6; diff --git a/indra/llmath/CMakeLists.txt b/indra/llmath/CMakeLists.txt index 999bee0a3f..552e820127 100644 --- a/indra/llmath/CMakeLists.txt +++ b/indra/llmath/CMakeLists.txt @@ -4,6 +4,7 @@ project(llmath)  include(00-Common)  include(LLCommon) +include(bugsplat)  include(Boost)  include_directories( diff --git a/indra/llmessage/llcoproceduremanager.cpp b/indra/llmessage/llcoproceduremanager.cpp index 4d76dacdf7..be014e7b1e 100644 --- a/indra/llmessage/llcoproceduremanager.cpp +++ b/indra/llmessage/llcoproceduremanager.cpp @@ -138,13 +138,24 @@ LLCoprocedureManager::~LLCoprocedureManager()      close();  } -LLCoprocedureManager::poolPtr_t LLCoprocedureManager::initializePool(const std::string &poolName) +void LLCoprocedureManager::initializePool(const std::string &poolName)  { +    poolMap_t::iterator it = mPoolMap.find(poolName); + +    if (it != mPoolMap.end()) +    { +        // Pools are not supposed to be initialized twice +        // Todo: ideally restrict init to STATE_FIRST +        LL_ERRS() << "Pool is already present " << poolName << LL_ENDL; +        return; +    } +      // Attempt to look up a pool size in the configuration.  If found use that      std::string keyName = "PoolSize" + poolName;      int size = 0;      LL_ERRS_IF(poolName.empty(), "CoprocedureManager") << "Poolname must not be empty" << LL_ENDL; +    LL_INFOS("CoprocedureManager") << "Initializing pool " << poolName << LL_ENDL;      if (mPropertyQueryFn)      { @@ -171,8 +182,6 @@ LLCoprocedureManager::poolPtr_t LLCoprocedureManager::initializePool(const std::      bool inserted = mPoolMap.emplace(poolName, pool).second;      LL_ERRS_IF(!inserted, "CoprocedureManager") << "Unable to add pool named \"" << poolName << "\" to map. FATAL!" << LL_ENDL; - -    return pool;  }  //------------------------------------------------------------------------- @@ -182,20 +191,28 @@ LLUUID LLCoprocedureManager::enqueueCoprocedure(const std::string &pool, const s      // not exist, create it.      poolMap_t::iterator it = mPoolMap.find(pool); -    poolPtr_t targetPool = (it != mPoolMap.end()) ? it->second : initializePool(pool); +    if (it == mPoolMap.end()) +    { +        // initializing pools in enqueueCoprocedure is not thread safe, +        // at the moment pools need to be initialized manually +        LL_ERRS() << "Uninitialized pool " << pool << LL_ENDL; +    } +    poolPtr_t targetPool = it->second;      return targetPool->enqueueCoprocedure(name, proc);  }  void LLCoprocedureManager::setPropertyMethods(SettingQuery_t queryfn, SettingUpdate_t updatefn)  {      // functions to discover and store the pool sizes +    // Might be a better idea to make an initializePool(name, size) to init everything externally      mPropertyQueryFn = queryfn;      mPropertyDefineFn = updatefn; -    // workaround until we get mutex into initializePool -    initializePool("AssetStorage");      initializePool("Upload"); +    initializePool("AIS"); // it might be better to have some kind of on-demand initialization for AIS +    // "ExpCache" pool gets initialized in LLExperienceCache +    // asset storage pool gets initialized in LLViewerAssetStorage  }  //------------------------------------------------------------------------- diff --git a/indra/llmessage/llcoproceduremanager.h b/indra/llmessage/llcoproceduremanager.h index d5557c129f..2d460826ff 100644 --- a/indra/llmessage/llcoproceduremanager.h +++ b/indra/llmessage/llcoproceduremanager.h @@ -79,6 +79,8 @@ public:      void close();      void close(const std::string &pool); + +    void initializePool(const std::string &poolName);  private: @@ -87,8 +89,6 @@ private:      poolMap_t mPoolMap; -    poolPtr_t initializePool(const std::string &poolName); -      SettingQuery_t mPropertyQueryFn;      SettingUpdate_t mPropertyDefineFn; diff --git a/indra/llmessage/llexperiencecache.cpp b/indra/llmessage/llexperiencecache.cpp index 64c01bd9eb..db22ad2ea3 100644 --- a/indra/llmessage/llexperiencecache.cpp +++ b/indra/llmessage/llexperiencecache.cpp @@ -108,6 +108,8 @@ void LLExperienceCache::initSingleton()          cache_stream >> (*this);      } +    LLCoprocedureManager::instance().initializePool("ExpCache"); +      LLCoros::instance().launch("LLExperienceCache::idleCoro",          boost::bind(&LLExperienceCache::idleCoro, this)); diff --git a/indra/llmessage/tests/llcoproceduremanager_test.cpp b/indra/llmessage/tests/llcoproceduremanager_test.cpp index 9db13a37b5..6424117ef3 100644 --- a/indra/llmessage/tests/llcoproceduremanager_test.cpp +++ b/indra/llmessage/tests/llcoproceduremanager_test.cpp @@ -91,6 +91,7 @@ namespace tut      {          Sync sync;          int foo = 0; +        LLCoprocedureManager::instance().initializePool("PoolName");          LLUUID queueId = LLCoprocedureManager::instance().enqueueCoprocedure("PoolName", "ProcName",              [&foo, &sync] (LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t & ptr, const LLUUID & id) {                  sync.bump(); diff --git a/indra/llplugin/llpluginprocessparent.cpp b/indra/llplugin/llpluginprocessparent.cpp index 7d18bae947..e5b4dec1bd 100644 --- a/indra/llplugin/llpluginprocessparent.cpp +++ b/indra/llplugin/llpluginprocessparent.cpp @@ -154,9 +154,9 @@ void LLPluginProcessParent::shutdown()      {          EState state = (*it).second->mState;          if (state != STATE_CLEANUP -            || state != STATE_EXITING -            || state != STATE_DONE -            || state != STATE_ERROR) +            && state != STATE_EXITING +            && state != STATE_DONE +            && state != STATE_ERROR)          {              (*it).second->setState(STATE_GOODBYE);          } diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index d515fc707a..03b6aac20c 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -50,6 +50,7 @@ U32 LLRender::sUIVerts = 0;  U32 LLTexUnit::sWhiteTexture = 0;  bool LLRender::sGLCoreProfile = false;  bool LLRender::sNsightDebugSupport = false; +LLVector2 LLRender::sUIGLScaleFactor = LLVector2(1.f, 1.f);  static const U32 LL_NUM_TEXTURE_LAYERS = 32;   static const U32 LL_NUM_LIGHT_UNITS = 8; diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h index 41f4fe4017..af8568f8a3 100644 --- a/indra/llrender/llrender.h +++ b/indra/llrender/llrender.h @@ -463,6 +463,7 @@ public:  	static U32 sUIVerts;  	static bool sGLCoreProfile;  	static bool sNsightDebugSupport; +	static LLVector2 sUIGLScaleFactor;  private:  	friend class LLLightState; diff --git a/indra/llrender/llrender2dutils.cpp b/indra/llrender/llrender2dutils.cpp index 801b945806..dd34f3e383 100644 --- a/indra/llrender/llrender2dutils.cpp +++ b/indra/llrender/llrender2dutils.cpp @@ -106,11 +106,10 @@ void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, S32 pixe  	top += LLFontGL::sCurOrigin.mY;  	gGL.loadUIIdentity(); -	LLRender2D *r2d_inst = LLRender2D::getInstance(); -	gl_rect_2d(llfloor((F32)left * r2d_inst->mGLScaleFactor.mV[VX]) - pixel_offset, -				llfloor((F32)top * r2d_inst->mGLScaleFactor.mV[VY]) + pixel_offset, -				llfloor((F32)right * r2d_inst->mGLScaleFactor.mV[VX]) + pixel_offset, -				llfloor((F32)bottom * r2d_inst->mGLScaleFactor.mV[VY]) - pixel_offset, +	gl_rect_2d(llfloor((F32)left * LLRender::sUIGLScaleFactor.mV[VX]) - pixel_offset, +				llfloor((F32)top * LLRender::sUIGLScaleFactor.mV[VY]) + pixel_offset, +				llfloor((F32)right * LLRender::sUIGLScaleFactor.mV[VX]) + pixel_offset, +				llfloor((F32)bottom * LLRender::sUIGLScaleFactor.mV[VY]) - pixel_offset,  				filled);  	gGL.popUIMatrix();  } @@ -1568,7 +1567,6 @@ void gl_segmented_rect_3d_tex(const LLRectf& clip_rect, const LLRectf& center_uv  LLRender2D::LLRender2D(LLImageProviderInterface* image_provider)  { -	mGLScaleFactor = LLVector2(1.f, 1.f);  	mImageProvider = image_provider;  	if(mImageProvider)  	{ @@ -1585,7 +1583,7 @@ LLRender2D::~LLRender2D()  	}  } - +// static  void LLRender2D::translate(F32 x, F32 y, F32 z)  {  	gGL.translateUI(x,y,z); @@ -1594,12 +1592,14 @@ void LLRender2D::translate(F32 x, F32 y, F32 z)  	LLFontGL::sCurDepth += z;  } +// static  void LLRender2D::pushMatrix()  {  	gGL.pushUIMatrix();  	LLFontGL::sOriginStack.push_back(std::make_pair(LLFontGL::sCurOrigin, LLFontGL::sCurDepth));  } +// static  void LLRender2D::popMatrix()  {  	gGL.popUIMatrix(); @@ -1608,6 +1608,7 @@ void LLRender2D::popMatrix()  	LLFontGL::sOriginStack.pop_back();  } +// static  void LLRender2D::loadIdentity()  {  	gGL.loadUIIdentity();  @@ -1616,15 +1617,11 @@ void LLRender2D::loadIdentity()  	LLFontGL::sCurDepth = 0.f;  } -void LLRender2D::setScaleFactor(const LLVector2 &scale_factor) -{ -	mGLScaleFactor = scale_factor; -} - +// static  void LLRender2D::setLineWidth(F32 width)  {  	gGL.flush(); -	glLineWidth(width * lerp(mGLScaleFactor.mV[VX], mGLScaleFactor.mV[VY], 0.5f)); +	glLineWidth(width * lerp(LLRender::sUIGLScaleFactor.mV[VX], LLRender::sUIGLScaleFactor.mV[VY], 0.5f));  }  LLPointer<LLUIImage> LLRender2D::getUIImageByID(const LLUUID& image_id, S32 priority) diff --git a/indra/llrender/llrender2dutils.h b/indra/llrender/llrender2dutils.h index 8c01784071..206e68f084 100644 --- a/indra/llrender/llrender2dutils.h +++ b/indra/llrender/llrender2dutils.h @@ -128,19 +128,16 @@ class LLRender2D : public LLParamSingleton<LLRender2D>  	LOG_CLASS(LLRender2D);  	~LLRender2D();  public: -	void pushMatrix(); -	void popMatrix(); -	void loadIdentity(); -	void translate(F32 x, F32 y, F32 z = 0.0f); +	static void pushMatrix(); +	static void popMatrix(); +	static void loadIdentity(); +	static void translate(F32 x, F32 y, F32 z = 0.0f); -	void setLineWidth(F32 width); -	void setScaleFactor(const LLVector2& scale_factor); +	static void setLineWidth(F32 width);  	LLPointer<LLUIImage> getUIImageByID(const LLUUID& image_id, S32 priority = 0);  	LLPointer<LLUIImage> getUIImage(const std::string& name, S32 priority = 0); -	LLVector2		mGLScaleFactor; -  protected:  	// since LLRender2D has no control of image provider's lifecycle  	// we need a way to tell LLRender2D that provider died and diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt index cce618487b..f781ff4110 100644 --- a/indra/llui/CMakeLists.txt +++ b/indra/llui/CMakeLists.txt @@ -122,6 +122,7 @@ set(llui_SOURCE_FILES      lluictrl.cpp      lluictrlfactory.cpp      lluistring.cpp +    lluiusage.cpp      llundo.cpp      llurlaction.cpp      llurlentry.cpp @@ -241,6 +242,7 @@ set(llui_HEADER_FILES      llui.h      lluicolor.h      lluistring.h +    lluiusage.h      llundo.h      llurlaction.h      llurlentry.h diff --git a/indra/llui/llaccordionctrltab.cpp b/indra/llui/llaccordionctrltab.cpp index 098621b543..04485c6262 100644 --- a/indra/llui/llaccordionctrltab.cpp +++ b/indra/llui/llaccordionctrltab.cpp @@ -1006,7 +1006,7 @@ void LLAccordionCtrlTab::drawChild(const LLRect& root_rect,LLView* child)  		LLRect screen_rect;  		localRectToScreen(child->getRect(),&screen_rect); -		if ( root_rect.overlaps(screen_rect)  && LLUI::getInstance()->mDirtyRect.overlaps(screen_rect)) +		if ( root_rect.overlaps(screen_rect)  && sDirtyRect.overlaps(screen_rect))  		{  			gGL.matrixMode(LLRender::MM_MODELVIEW);  			LLUI::pushMatrix(); diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp index 9682c3bc10..0e59fdf519 100644 --- a/indra/llui/llbutton.cpp +++ b/indra/llui/llbutton.cpp @@ -47,6 +47,7 @@  #include "llnotificationsutil.h"  #include "llrender.h"  #include "lluictrlfactory.h" +#include "lluiusage.h"  #include "llhelp.h"  #include "lldockablefloater.h"  #include "llviewereventrecorder.h" @@ -437,6 +438,13 @@ BOOL LLButton::handleMouseDown(S32 x, S32 y, MASK mask)  			setFocus(TRUE);  		} +		if (!mFunctionName.empty()) +		{ +			LL_DEBUGS("UIUsage") << "calling mouse down function " << mFunctionName << LL_ENDL; +			LLUIUsage::instance().logCommand(mFunctionName); +			LLUIUsage::instance().logControl(getPathname()); +		} +  		/*  		 * ATTENTION! This call fires another mouse down callback.  		 * If you wish to remove this call emit that signal directly diff --git a/indra/llui/llchat.h b/indra/llui/llchat.h index f5b242fdfc..c39e44200c 100644 --- a/indra/llui/llchat.h +++ b/indra/llui/llchat.h @@ -37,7 +37,8 @@ typedef enum e_chat_source_type  	CHAT_SOURCE_SYSTEM = 0,  	CHAT_SOURCE_AGENT = 1,  	CHAT_SOURCE_OBJECT = 2, -	CHAT_SOURCE_UNKNOWN = 3 +	CHAT_SOURCE_TELEPORT = 3, +	CHAT_SOURCE_UNKNOWN = 4  } EChatSourceType;  typedef enum e_chat_type @@ -64,7 +65,8 @@ typedef enum e_chat_style  {  	CHAT_STYLE_NORMAL,  	CHAT_STYLE_IRC, -	CHAT_STYLE_HISTORY +	CHAT_STYLE_HISTORY, +	CHAT_STYLE_TELEPORT_SEP  }EChatStyle;  // A piece of chat diff --git a/indra/llui/llconsole.cpp b/indra/llui/llconsole.cpp index 7817d99aef..8fc2978bdd 100644 --- a/indra/llui/llconsole.cpp +++ b/indra/llui/llconsole.cpp @@ -180,7 +180,9 @@ void LLConsole::draw()  	LLUIImagePtr imagep = LLUI::getUIImage("transparent"); -	F32 console_opacity = llclamp(LLUI::getInstance()->mSettingGroups["config"]->getF32("ConsoleBackgroundOpacity"), 0.f, 1.f); +	static LLCachedControl<F32> console_bg_opacity(*LLUI::getInstance()->mSettingGroups["config"], "ConsoleBackgroundOpacity", 0.7f); +	F32 console_opacity = llclamp(console_bg_opacity(), 0.f, 1.f); +  	LLColor4 color = LLUIColorTable::instance().getColor("ConsoleBackground");  	color.mV[VALPHA] *= console_opacity; diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index 61f2767b5c..f20c859ac4 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -58,6 +58,7 @@  #include "llhelp.h"  #include "llmultifloater.h"  #include "llsdutil.h" +#include "lluiusage.h"  #include <boost/foreach.hpp> @@ -198,7 +199,9 @@ LLFloater::Params::Params()  	help_pressed_image("help_pressed_image"),  	open_callback("open_callback"),  	close_callback("close_callback"), -	follows("follows") +	follows("follows"), +	rel_x("rel_x", 0), +	rel_y("rel_y", 0)  {  	changeDefault(visible, false);  } @@ -268,6 +271,8 @@ LLFloater::LLFloater(const LLSD& key, const LLFloater::Params& p)  	mHasBeenDraggedWhileMinimized(FALSE),  	mPreviousMinimizedBottom(0),  	mPreviousMinimizedLeft(0), +	mDefaultRelativeX(p.rel_x), +	mDefaultRelativeY(p.rel_y),  	mMinimizeSignal(NULL)  //	mNotificationContext(NULL)  { @@ -377,13 +382,15 @@ void LLFloater::layoutDragHandle()  // static  void LLFloater::updateActiveFloaterTransparency()  { -    sActiveControlTransparency = LLUI::getInstance()->mSettingGroups["config"]->getF32("ActiveFloaterTransparency"); +    static LLCachedControl<F32> active_transparency(*LLUI::getInstance()->mSettingGroups["config"], "ActiveFloaterTransparency", 1.f); +    sActiveControlTransparency = active_transparency;  }  // static  void LLFloater::updateInactiveFloaterTransparency()  { -    sInactiveControlTransparency = LLUI::getInstance()->mSettingGroups["config"]->getF32("InactiveFloaterTransparency"); +    static LLCachedControl<F32> inactive_transparency(*LLUI::getInstance()->mSettingGroups["config"], "InactiveFloaterTransparency", 0.95f); +    sInactiveControlTransparency = inactive_transparency;  }  void LLFloater::addResizeCtrls() @@ -506,7 +513,12 @@ void LLFloater::destroy()  // virtual  LLFloater::~LLFloater()  { -	LLFloaterReg::removeInstance(mInstanceName, mKey); +    if (!isDead()) +    { +        // If it's dead, instance is supposed to be already removed, and +        // in case of single instance we can remove new one by accident +        LLFloaterReg::removeInstance(mInstanceName, mKey); +    }  	if( gFocusMgr.childHasKeyboardFocus(this))  	{ @@ -938,6 +950,15 @@ bool LLFloater::applyRectControl()  			saved_rect = true;  		} +		else if ((mDefaultRelativeX != 0) && (mDefaultRelativeY != 0)) +		{ +			mPosition.mX = mDefaultRelativeX; +			mPosition.mY = mDefaultRelativeY; +			mPositioning = LLFloaterEnums::POSITIONING_RELATIVE; +			applyRelativePosition(); + +			saved_rect = true; +		}  		// remember updated position  		if (rect_specified) @@ -1635,6 +1656,7 @@ void LLFloater::bringToFront( S32 x, S32 y )  // virtual  void LLFloater::setVisibleAndFrontmost(BOOL take_focus,const LLSD& key)  { +	LLUIUsage::instance().logFloater(getInstanceName());  	LLMultiFloater* hostp = getHost();  	if (hostp)  	{ @@ -3202,6 +3224,9 @@ void LLFloater::initFromParams(const LLFloater::Params& p)  	mSingleInstance = p.single_instance;  	mReuseInstance = p.reuse_instance.isProvided() ? p.reuse_instance : p.single_instance; +	mDefaultRelativeX = p.rel_x; +	mDefaultRelativeY = p.rel_y; +  	mPositioning = p.positioning;  	mSaveRect = p.save_rect; diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h index 8dffe3c255..db0bbfef30 100644 --- a/indra/llui/llfloater.h +++ b/indra/llui/llfloater.h @@ -172,6 +172,9 @@ public:  		Optional<S32>			header_height,  								legacy_header_height; // HACK see initFromXML() +		Optional<F32>			rel_x, +								rel_y; +  		// Images for top-right controls  		Optional<LLUIImage*>	close_image,  								restore_image, @@ -522,6 +525,9 @@ private:  	BOOL			mHasBeenDraggedWhileMinimized;  	S32				mPreviousMinimizedBottom;  	S32				mPreviousMinimizedLeft; + +	F32				mDefaultRelativeX; +	F32				mDefaultRelativeY;  }; diff --git a/indra/llui/llfloaterreg.cpp b/indra/llui/llfloaterreg.cpp index 85e07fc6a6..36a0cb0fd0 100644 --- a/indra/llui/llfloaterreg.cpp +++ b/indra/llui/llfloaterreg.cpp @@ -32,6 +32,7 @@  #include "llfloater.h"  #include "llmultifloater.h"  #include "llfloaterreglistener.h" +#include "lluiusage.h"  //******************************************************* @@ -57,6 +58,12 @@ void LLFloaterReg::add(const std::string& name, const std::string& filename, con  }  //static +bool LLFloaterReg::isRegistered(const std::string& name) +{ +    return sBuildMap.find(name) != sBuildMap.end(); +} + +//static  LLFloater* LLFloaterReg::getLastFloaterInGroup(const std::string& name)  {  	const std::string& groupname = sGroupMap[name]; @@ -472,7 +479,6 @@ void LLFloaterReg::toggleInstanceOrBringToFront(const LLSD& sdname, const LLSD&  	std::string name = sdname.asString();  	LLFloater* instance = getInstance(name, key);  -  	if (!instance)  	{  		LL_DEBUGS() << "Unable to get instance of floater '" << name << "'" << LL_ENDL; diff --git a/indra/llui/llfloaterreg.h b/indra/llui/llfloaterreg.h index e3b17dcb4f..a457a15673 100644 --- a/indra/llui/llfloaterreg.h +++ b/indra/llui/llfloaterreg.h @@ -85,6 +85,7 @@ public:  	static void add(const std::string& name, const std::string& file, const LLFloaterBuildFunc& func,  					const std::string& groupname = LLStringUtil::null); +	static bool isRegistered(const std::string& name);  	// Helpers  	static LLFloater* getLastFloaterInGroup(const std::string& name); diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp index 0c1dcc301b..622c9edba7 100644 --- a/indra/llui/llfolderview.cpp +++ b/indra/llui/llfolderview.cpp @@ -342,9 +342,9 @@ static LLTrace::BlockTimerStatHandle FTM_FILTER("Filter Folder View");  void LLFolderView::filter( LLFolderViewFilter& filter )  {  	LL_RECORD_BLOCK_TIME(FTM_FILTER); -    static LLCachedControl<S32> filter_visible(*LLUI::getInstance()->mSettingGroups["config"], "FilterItemsMaxTimePerFrameVisible", 10); -    static LLCachedControl<S32> filter_hidden(*LLUI::getInstance()->mSettingGroups["config"], "FilterItemsMaxTimePerFrameUnvisible", 1); -    filter.resetTime(llclamp(mParentPanel.get()->getVisible() ? filter_visible() : filter_hidden(), 1, 100)); +    static LLCachedControl<S32> time_visible(*LLUI::getInstance()->mSettingGroups["config"], "FilterItemsMaxTimePerFrameVisible", 10); +    static LLCachedControl<S32> time_invisible(*LLUI::getInstance()->mSettingGroups["config"], "FilterItemsMaxTimePerFrameUnvisible", 1); +    filter.resetTime(llclamp((mParentPanel.get()->getVisible() ? time_visible() : time_invisible()), 1, 100));      // Note: we filter the model, not the view  	getViewModelItem()->filter(filter); @@ -663,7 +663,8 @@ void LLFolderView::draw()  		closeAutoOpenedFolders();  	} -	if (mSearchTimer.getElapsedTimeF32() > LLUI::getInstance()->mSettingGroups["config"]->getF32("TypeAheadTimeout") || !mSearchString.size()) +	static LLCachedControl<F32> type_ahead_timeout(*LLUI::getInstance()->mSettingGroups["config"], "TypeAheadTimeout", 1.5f); +	if (mSearchTimer.getElapsedTimeF32() > type_ahead_timeout || !mSearchString.size())  	{  		mSearchString.clear();  	} diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp index 1c6c7b1b35..285bf9f484 100644 --- a/indra/llui/llfolderviewitem.cpp +++ b/indra/llui/llfolderviewitem.cpp @@ -962,9 +962,10 @@ void LLFolderViewItem::draw()  	//      if (filter_string_length > 0)      { -        F32 match_string_left = text_left + font->getWidthF32(combined_string, 0, mViewModelItem->getFilterStringOffset()); +        S32 filter_offset = mViewModelItem->getFilterStringOffset(); +        F32 match_string_left = text_left + font->getWidthF32(combined_string, 0, filter_offset + filter_string_length) - font->getWidthF32(combined_string, filter_offset, filter_string_length);          F32 yy = (F32)getRect().getHeight() - font->getLineHeight() - (F32)mTextPad - (F32)TOP_PAD; -        font->renderUTF8( combined_string, mViewModelItem->getFilterStringOffset(), match_string_left, yy, +        font->renderUTF8( combined_string, filter_offset, match_string_left, yy,              sFilterTextColor, LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,              filter_string_length, S32_MAX, &right_x, FALSE );      } @@ -1607,7 +1608,7 @@ void LLFolderViewFolder::destroyView()  // extractItem() removes the specified item from the folder, but  // doesn't delete it. -void LLFolderViewFolder::extractItem( LLFolderViewItem* item ) +void LLFolderViewFolder::extractItem( LLFolderViewItem* item, bool deparent_model )  {  	if (item->isSelected())  		getRoot()->clearSelection(); @@ -1630,7 +1631,11 @@ void LLFolderViewFolder::extractItem( LLFolderViewItem* item )  		mItems.erase(it);  	}  	//item has been removed, need to update filter -	getViewModelItem()->removeChild(item->getViewModelItem()); +    if (deparent_model) +    { +        // in some cases model does not belong to parent view, is shared between views +        getViewModelItem()->removeChild(item->getViewModelItem()); +    }  	//because an item is going away regardless of filter status, force rearrange  	requestArrange();  	removeChild(item); diff --git a/indra/llui/llfolderviewitem.h b/indra/llui/llfolderviewitem.h index da09d139e9..616d2e7d86 100644 --- a/indra/llui/llfolderviewitem.h +++ b/indra/llui/llfolderviewitem.h @@ -387,7 +387,7 @@ public:  	// extractItem() removes the specified item from the folder, but  	// doesn't delete it. -	virtual void extractItem( LLFolderViewItem* item ); +	virtual void extractItem( LLFolderViewItem* item, bool deparent_model = true);  	// This function is called by a child that needs to be resorted.  	void resort(LLFolderViewItem* item); diff --git a/indra/llui/llfolderviewmodel.cpp b/indra/llui/llfolderviewmodel.cpp index ea106b5fae..93122503d1 100644 --- a/indra/llui/llfolderviewmodel.cpp +++ b/indra/llui/llfolderviewmodel.cpp @@ -48,9 +48,9 @@ std::string LLFolderViewModelCommon::getStatusText()  void LLFolderViewModelCommon::filter()  { -    static LLCachedControl<S32> filter_visible(*LLUI::getInstance()->mSettingGroups["config"], "FilterItemsMaxTimePerFrameVisible", 10); -    getFilter().resetTime(llclamp(filter_visible(), 1, 100)); -	mFolderView->getViewModelItem()->filter(getFilter()); +    static LLCachedControl<S32> max_time(*LLUI::getInstance()->mSettingGroups["config"], "FilterItemsMaxTimePerFrameVisible", 10); +    getFilter().resetTime(llclamp(max_time(), 1, 100)); +    mFolderView->getViewModelItem()->filter(getFilter());  }  bool LLFolderViewModelItemCommon::hasFilterStringMatch() diff --git a/indra/llui/lllineeditor.h b/indra/llui/lllineeditor.h index aa5779d45f..f84625bea7 100644 --- a/indra/llui/lllineeditor.h +++ b/indra/llui/lllineeditor.h @@ -283,6 +283,9 @@ public:  	void			resetContextMenu() { setContextMenu(NULL); }; +	void			setBgImage(LLPointer<LLUIImage> image) { mBgImage = image; } +	void			setBgImageFocused(LLPointer<LLUIImage> image) { mBgImageFocused = image; } +  private:  	// private helper methods diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index 37dbe9b40e..cdaf03ebde 100644 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -79,7 +79,7 @@ const U32 LEFT_PAD_PIXELS = 3;  const U32 LEFT_WIDTH_PIXELS = 15;  const U32 LEFT_PLAIN_PIXELS = LEFT_PAD_PIXELS + LEFT_WIDTH_PIXELS; -const U32 RIGHT_PAD_PIXELS = 2; +const U32 RIGHT_PAD_PIXELS = 7;  const U32 RIGHT_WIDTH_PIXELS = 15;  const U32 RIGHT_PLAIN_PIXELS = RIGHT_PAD_PIXELS + RIGHT_WIDTH_PIXELS; @@ -95,7 +95,7 @@ const std::string SEPARATOR_NAME("separator");  const std::string VERTICAL_SEPARATOR_LABEL( "|" );  const std::string LLMenuGL::BOOLEAN_TRUE_PREFIX( "\xE2\x9C\x94" ); // U+2714 HEAVY CHECK MARK -const std::string LLMenuGL::BRANCH_SUFFIX( "\xE2\x96\xB6" ); // U+25B6 BLACK RIGHT-POINTING TRIANGLE +const std::string LLMenuGL::BRANCH_SUFFIX( "\xe2\x96\xb8" ); // U+25B6 BLACK RIGHT-POINTING TRIANGLE  const std::string LLMenuGL::ARROW_UP  ("^^^^^^^");  const std::string LLMenuGL::ARROW_DOWN("vvvvvvv"); diff --git a/indra/llui/llmultislider.cpp b/indra/llui/llmultislider.cpp index acfe4a0cba..f89064d59a 100644 --- a/indra/llui/llmultislider.cpp +++ b/indra/llui/llmultislider.cpp @@ -136,6 +136,7 @@ LLMultiSlider::LLMultiSlider(const LLMultiSlider::Params& p)  		}  	} +    mRoundedSquareImgp = LLUI::getUIImage("Rounded_Square");  	if (p.thumb_image.isProvided())  	{  		mThumbImagep = LLUI::getUIImage(p.thumb_image()); @@ -666,8 +667,6 @@ void LLMultiSlider::draw()  	F32 opacity = getEnabled() ? 1.f : 0.3f;  	// Track -	LLUIImagePtr thumb_imagep = LLUI::getUIImage("Rounded_Square"); -  	static LLUICachedControl<S32> multi_track_height_width ("UIMultiTrackHeight", 0);  	S32 height_offset = 0;  	S32 width_offset = 0; @@ -685,7 +684,7 @@ void LLMultiSlider::draw()  	if(mDrawTrack)  	{  		track_rect.stretch(-1); -		thumb_imagep->draw(track_rect, mTrackColor.get() % opacity); +		mRoundedSquareImgp->draw(track_rect, mTrackColor.get() % opacity);  	}  	// if we're supposed to use a drawn triangle @@ -704,7 +703,7 @@ void LLMultiSlider::draw()  				mTriangleColor.get() % opacity, TRUE);  		}  	} -	else if (!thumb_imagep && !mThumbImagep) +	else if (!mRoundedSquareImgp && !mThumbImagep)  	{  		// draw all the thumbs  		curSldrIt = mThumbRects.end(); @@ -757,7 +756,7 @@ void LLMultiSlider::draw()  			}  			else  			{ -				thumb_imagep->drawSolid(mDragStartThumbRect, mThumbCenterColor.get() % 0.3f); +                mRoundedSquareImgp->drawSolid(mDragStartThumbRect, mThumbCenterColor.get() % 0.3f);  			}  		} @@ -772,7 +771,7 @@ void LLMultiSlider::draw()  				}  				else  				{ -					thumb_imagep->drawBorder(mThumbRects[mCurSlider], gFocusMgr.getFocusColor(), gFocusMgr.getFocusFlashWidth()); +                    mRoundedSquareImgp->drawBorder(mThumbRects[mCurSlider], gFocusMgr.getFocusColor(), gFocusMgr.getFocusFlashWidth());  				}  			}  		} @@ -784,7 +783,7 @@ void LLMultiSlider::draw()              }              else              { -                thumb_imagep->drawBorder(mThumbRects[mHoverSlider], gFocusMgr.getFocusColor(), gFocusMgr.getFocusFlashWidth()); +                mRoundedSquareImgp->drawBorder(mThumbRects[mHoverSlider], gFocusMgr.getFocusColor(), gFocusMgr.getFocusFlashWidth());              }          } @@ -822,11 +821,11 @@ void LLMultiSlider::draw()  			}  			else if (capture == this)  			{ -				thumb_imagep->drawSolid(mIt->second, curThumbColor); +                mRoundedSquareImgp->drawSolid(mIt->second, curThumbColor);  			}  			else  			{ -				thumb_imagep->drawSolid(mIt->second, curThumbColor % opacity); +                mRoundedSquareImgp->drawSolid(mIt->second, curThumbColor % opacity);  			}  		} @@ -846,11 +845,11 @@ void LLMultiSlider::draw()  			}  			else if (capture == this)  			{ -				thumb_imagep->drawSolid(curSldrIt->second, mThumbCenterSelectedColor.get()); +                mRoundedSquareImgp->drawSolid(curSldrIt->second, mThumbCenterSelectedColor.get());  			}  			else  			{ -				thumb_imagep->drawSolid(curSldrIt->second, mThumbCenterSelectedColor.get() % opacity); +                mRoundedSquareImgp->drawSolid(curSldrIt->second, mThumbCenterSelectedColor.get() % opacity);  			}  		}  		if(hoverSldrIt != mThumbRects.end())  @@ -861,7 +860,7 @@ void LLMultiSlider::draw()  			}  			else  			{ -				thumb_imagep->drawSolid(hoverSldrIt->second, mThumbCenterSelectedColor.get()); +                mRoundedSquareImgp->drawSolid(hoverSldrIt->second, mThumbCenterSelectedColor.get());  			}  		}  	} diff --git a/indra/llui/llmultislider.h b/indra/llui/llmultislider.h index 99a78d6e09..3cb4b760b0 100644 --- a/indra/llui/llmultislider.h +++ b/indra/llui/llmultislider.h @@ -150,6 +150,7 @@ protected:  	LLUIColor		mDisabledThumbColor;  	LLUIColor		mTriangleColor;  	LLUIImagePtr	mThumbImagep; //blimps on the slider, for now no 'disabled' support +    LLUIImagePtr	mRoundedSquareImgp; //blimps on the slider, for now no 'disabled' support  	const EOrientation	mOrientation; diff --git a/indra/llui/llnotificationptr.h b/indra/llui/llnotificationptr.h index acc047527f..580f353c7d 100644 --- a/indra/llui/llnotificationptr.h +++ b/indra/llui/llnotificationptr.h @@ -27,9 +27,8 @@  // Many classes just store a single LLNotificationPtr  // and llnotifications.h is very large, so define this ligher header. -#include <boost/shared_ptr.hpp>  class LLNotification; -typedef boost::shared_ptr<LLNotification> LLNotificationPtr; +typedef std::shared_ptr<LLNotification> LLNotificationPtr;  #endif diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp index 06ec648178..b791a19c2b 100644 --- a/indra/llui/llnotifications.cpp +++ b/indra/llui/llnotifications.cpp @@ -77,6 +77,7 @@ LLNotificationForm::FormButton::FormButton()  	text("text"),  	ignore("ignore"),  	is_default("default"), +	width("width", 0),  	type("type")  {  	// set type here so it gets serialized diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h index 2f4578da17..b1123d27e5 100644 --- a/indra/llui/llnotifications.h +++ b/indra/llui/llnotifications.h @@ -85,7 +85,6 @@  #include <boost/utility.hpp>  #include <boost/shared_ptr.hpp> -#include <boost/enable_shared_from_this.hpp>  #include <boost/type_traits.hpp>  #include <boost/signals2.hpp>  #include <boost/range.hpp> @@ -191,6 +190,7 @@ public:  		Mandatory<std::string>	text;  		Optional<std::string>	ignore;  		Optional<bool>			is_default; +		Optional<S32>			width;  		Mandatory<std::string>	type; @@ -304,7 +304,7 @@ typedef boost::shared_ptr<LLNotificationVisibilityRule> LLNotificationVisibility   */  class LLNotification  :   	boost::noncopyable, -	public boost::enable_shared_from_this<LLNotification> +	public std::enable_shared_from_this<LLNotification>  {  LOG_CLASS(LLNotification);  friend class LLNotifications; @@ -743,7 +743,10 @@ public:  	:	mFilter(filter),   		mItems()   	{} -	virtual ~LLNotificationChannelBase() {} +    virtual ~LLNotificationChannelBase() +    { +        mItems.clear(); +    }  	// you can also connect to a Channel, so you can be notified of  	// changes to this channel      LLBoundListener connectChanged(const LLEventListener& slot) @@ -873,6 +876,7 @@ class LLNotifications :  {  	LLSINGLETON(LLNotifications);  	LOG_CLASS(LLNotifications); +	virtual ~LLNotifications() {}  public: @@ -1070,7 +1074,11 @@ public:  	LLPersistentNotificationChannel()   		:	LLNotificationChannel("Persistent", "Visible", ¬ificationFilter)  	{} -	virtual ~LLPersistentNotificationChannel() {} + +    virtual ~LLPersistentNotificationChannel() +    { +        mHistory.clear(); +    }  	typedef std::vector<LLNotificationPtr> history_list_t;  	history_list_t::iterator beginHistory() { sortHistory(); return mHistory.begin(); } diff --git a/indra/llui/llscrolllistcolumn.cpp b/indra/llui/llscrolllistcolumn.cpp index cc9ff7a487..82b0415624 100644 --- a/indra/llui/llscrolllistcolumn.cpp +++ b/indra/llui/llscrolllistcolumn.cpp @@ -257,7 +257,7 @@ void LLScrollColumnHeader::updateResizeBars()  	for (col = 0; col < mColumn->mParentCtrl->getNumColumns(); col++)  	{  		LLScrollListColumn* columnp = mColumn->mParentCtrl->getColumn(col); -		if (columnp->mHeader && columnp->mHeader->canResize()) +		if (columnp && columnp->mHeader && columnp->mHeader->canResize())  		{  			num_resizable_columns++;  		} @@ -269,7 +269,7 @@ void LLScrollColumnHeader::updateResizeBars()  	for (col = 0; col < mColumn->mParentCtrl->getNumColumns(); col++)  	{  		LLScrollListColumn* columnp = mColumn->mParentCtrl->getColumn(col); -		if (!columnp->mHeader) continue; +		if (!columnp || !columnp->mHeader) continue;  		BOOL enable = num_resizable_columns >= 2 && num_resizers_enabled < (num_resizable_columns - 1) && columnp->mHeader->canResize();  		columnp->mHeader->enableResizeBar(enable);  		if (enable) diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index be85f1cb6a..de644185fd 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -743,12 +743,12 @@ void LLScrollListCtrl::updateColumns(bool force_update)  	LLScrollColumnHeader* last_header = NULL;  	for (column_ordered_it = mColumnsIndexed.begin(); column_ordered_it != mColumnsIndexed.end(); ++column_ordered_it)  	{ -		if ((*column_ordered_it)->getWidth() < 0) +		LLScrollListColumn* column = *column_ordered_it; +		if (!column || column->getWidth() < 0)  		{  			// skip hidden columns  			continue;  		} -		LLScrollListColumn* column = *column_ordered_it;  		if (column->mHeader)  		{ diff --git a/indra/llui/llsearcheditor.cpp b/indra/llui/llsearcheditor.cpp index 1fdd05a11c..bafeef41fb 100644 --- a/indra/llui/llsearcheditor.cpp +++ b/indra/llui/llsearcheditor.cpp @@ -34,7 +34,11 @@  LLSearchEditor::LLSearchEditor(const LLSearchEditor::Params& p)  :	LLUICtrl(p),  	mSearchButton(NULL), -	mClearButton(NULL) +	mClearButton(NULL), +	mEditorImage(p.background_image), +	mEditorImageFocused(p.background_image_focused), +	mEditorSearchImage(p.background_image_highlight), +	mHighlightTextField(p.highlight_text_field)  {  	S32 srch_btn_top = p.search_button.top_pad + p.search_button.rect.height;  	S32 srch_btn_right = p.search_button.rect.width + p.search_button.left_pad; @@ -57,6 +61,8 @@ LLSearchEditor::LLSearchEditor(const LLSearchEditor::Params& p)  	// Set up line editor.  	LLLineEditor::Params line_editor_params(p);  	line_editor_params.name("filter edit box"); +	line_editor_params.background_image(p.background_image); +	line_editor_params.background_image_focused(p.background_image_focused);  	line_editor_params.rect(getLocalRect());  	line_editor_params.follows.flags(FOLLOWS_ALL);  	line_editor_params.text_pad_left(text_pad_left); @@ -104,6 +110,20 @@ void LLSearchEditor::draw()  	if (mClearButton)  		mClearButton->setVisible(!mSearchEditor->getWText().empty()); +	if (mHighlightTextField) +	{	 +		if (!mSearchEditor->getWText().empty()) +		{ +			mSearchEditor->setBgImage(mEditorSearchImage); +			mSearchEditor->setBgImageFocused(mEditorSearchImage); +		} +		else +		{ +			mSearchEditor->setBgImage(mEditorImage); +			mSearchEditor->setBgImageFocused(mEditorImageFocused); +		} +	} +  	LLUICtrl::draw();  } diff --git a/indra/llui/llsearcheditor.h b/indra/llui/llsearcheditor.h index 3b12868225..c0f3c1d60c 100644 --- a/indra/llui/llsearcheditor.h +++ b/indra/llui/llsearcheditor.h @@ -47,14 +47,23 @@ public:  		Optional<LLButton::Params>	search_button,   									clear_button;  		Optional<bool>				search_button_visible,  -									clear_button_visible; +									clear_button_visible, +									highlight_text_field;  		Optional<commit_callback_t> keystroke_callback; +		Optional<LLUIImage*>		background_image, +									background_image_focused, +									background_image_highlight; +  		Params()  		:	search_button("search_button"),  			search_button_visible("search_button_visible"),  			clear_button("clear_button"),  -			clear_button_visible("clear_button_visible") +			clear_button_visible("clear_button_visible"), +			highlight_text_field("highlight_text_field"), +			background_image("background_image"), +			background_image_focused("background_image_focused"), +			background_image_highlight("background_image_highlight")  		{}  	}; @@ -93,6 +102,13 @@ protected:  	LLLineEditor* mSearchEditor;  	LLButton* mSearchButton;  	LLButton* mClearButton; + +	LLPointer<LLUIImage> mEditorImage; +	LLPointer<LLUIImage> mEditorImageFocused; +	LLPointer<LLUIImage> mEditorSearchImage; +	LLPointer<LLUIImage> mEditorSearchImageFocused; + +	bool mHighlightTextField;  };  #endif  // LL_SEARCHEDITOR_H diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp index e5527da5cb..0aa7a2d217 100644 --- a/indra/llui/lltabcontainer.cpp +++ b/indra/llui/lltabcontainer.cpp @@ -38,6 +38,7 @@  #include "llrender.h"  #include "llfloater.h"  #include "lltrans.h" +#include "lluiusage.h"  //---------------------------------------------------------------------------- @@ -1562,6 +1563,8 @@ BOOL LLTabContainer::setTab(S32 which)  			if (is_selected)  			{ +				LLUIUsage::instance().logPanel(tuple->mTabPanel->getName()); +  				// Make sure selected tab is within scroll region  				if (mIsVertical)  				{ diff --git a/indra/llui/lltoolbar.cpp b/indra/llui/lltoolbar.cpp index e6f466ec78..5150df25f2 100644 --- a/indra/llui/lltoolbar.cpp +++ b/indra/llui/lltoolbar.cpp @@ -967,6 +967,8 @@ LLToolBarButton* LLToolBar::createButton(const LLCommandId& id)  			executeStopParam.function_name = executeStopFunction;  			executeStopParam.parameter = commandp->executeStopParameters();  			LLUICtrl::commit_callback_t execute_func = initCommitCallback(executeParam); +			button->setFunctionName(commandp->executeFunctionName()); +			LL_DEBUGS("UIUsage") << "button function name a -> " << commandp->executeFunctionName() << LL_ENDL;  			LLUICtrl::commit_callback_t stop_func = initCommitCallback(executeStopParam);  			button->setMouseDownCallback(boost::bind(&LLToolBarButton::callIfEnabled, button, execute_func, _1, _2)); @@ -974,6 +976,8 @@ LLToolBarButton* LLToolBar::createButton(const LLCommandId& id)  		}  		else  		{ +			button->setFunctionName(commandp->executeFunctionName()); +			LL_DEBUGS("UIUsage") << "button function name b -> " << commandp->executeFunctionName() << LL_ENDL;  			button->setCommitCallback(executeParam);  		} @@ -1125,7 +1129,7 @@ BOOL LLToolBarButton::handleHover(S32 x, S32 y, MASK mask)  	BOOL handled = FALSE;  	S32 mouse_distance_squared = (x - mMouseDownX) * (x - mMouseDownX) + (y - mMouseDownY) * (y - mMouseDownY); -	S32 drag_threshold = LLUI::getInstance()->mSettingGroups["config"]->getS32("DragAndDropDistanceThreshold"); +	static LLCachedControl<S32> drag_threshold(*LLUI::getInstance()->mSettingGroups["config"], "DragAndDropDistanceThreshold", 3);  	if (mouse_distance_squared > drag_threshold * drag_threshold  		&& hasMouseCapture() &&   		mStartDragItemCallback && mHandleDragItemCallback) diff --git a/indra/llui/lltooltip.cpp b/indra/llui/lltooltip.cpp index 422534b781..2f56a8b1d0 100644 --- a/indra/llui/lltooltip.cpp +++ b/indra/llui/lltooltip.cpp @@ -358,8 +358,8 @@ void LLToolTip::draw()  	if (mFadeTimer.getStarted())  	{ -		F32 tool_tip_fade_time = LLUI::getInstance()->mSettingGroups["config"]->getF32("ToolTipFadeTime"); -		alpha = clamp_rescale(mFadeTimer.getElapsedTimeF32(), 0.f, tool_tip_fade_time, 1.f, 0.f); +		static LLCachedControl<F32> tool_tip_fade_time(*LLUI::getInstance()->mSettingGroups["config"], "ToolTipFadeTime", 0.2f); +		alpha = clamp_rescale(mFadeTimer.getElapsedTimeF32(), 0.f, tool_tip_fade_time(), 1.f, 0.f);  		if (alpha == 0.f)  		{  			// finished fading out, so hide ourselves diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp index 656b69d3ed..6f16745bd3 100644 --- a/indra/llui/llui.cpp +++ b/indra/llui/llui.cpp @@ -154,7 +154,6 @@ mAudioCallback(audio_callback),  mDeferredAudioCallback(deferred_audio_callback),  mWindow(NULL), // set later in startup  mRootView(NULL), -mDirty(FALSE),  mHelpImpl(NULL)  {  	LLRender2D::initParamSingleton(image_provider); @@ -203,19 +202,6 @@ void LLUI::setPopupFuncs(const add_popup_t& add_popup, const remove_popup_t& rem  	mClearPopupsFunc = clear_popups;  } -void LLUI::dirtyRect(LLRect rect) -{ -	if (!mDirty) -	{ -		mDirtyRect = rect; -		mDirty = TRUE; -	} -	else -	{ -		mDirtyRect.unionWith(rect); -	} -} -  void LLUI::setMousePositionScreen(S32 x, S32 y)  {  #if defined(LL_DARWIN) @@ -510,6 +496,18 @@ const LLView* LLUI::resolvePath(const LLView* context, const std::string& path)  	return context;  } +//static +LLVector2& LLUI::getScaleFactor() +{ +    return LLRender::sUIGLScaleFactor; +} + +//static +void LLUI::setScaleFactor(const LLVector2& scale_factor) +{ +    LLRender::sUIGLScaleFactor = scale_factor; +} +  // LLLocalClipRect and LLScreenClipRect moved to lllocalcliprect.h/cpp diff --git a/indra/llui/llui.h b/indra/llui/llui.h index 9856e551cc..30dbd7248f 100644 --- a/indra/llui/llui.h +++ b/indra/llui/llui.h @@ -245,10 +245,6 @@ public:  	void setPopupFuncs(const add_popup_t& add_popup, const remove_popup_t&, const clear_popups_t& ); -	LLRect	mDirtyRect; -	BOOL		mDirty; -	void		dirtyRect(LLRect rect); -  	// Return the ISO639 language name ("en", "ko", etc.) for the viewer UI.  	// http://www.loc.gov/standards/iso639-2/php/code_list.php  	std::string getUILanguage(); @@ -313,14 +309,14 @@ public:  	void positionViewNearMouse(LLView* view,	S32 spawn_x = S32_MAX, S32 spawn_y = S32_MAX);  	// LLRender2D wrappers -	static void pushMatrix() { LLRender2D::getInstance()->pushMatrix(); } -	static void popMatrix() { LLRender2D::getInstance()->popMatrix(); } -	static void loadIdentity() { LLRender2D::getInstance()->loadIdentity(); } -	static void translate(F32 x, F32 y, F32 z = 0.0f) { LLRender2D::getInstance()->translate(x, y, z); } - -	static LLVector2& getScaleFactor() { return LLRender2D::getInstance()->mGLScaleFactor; } -	static void setScaleFactor(const LLVector2& scale_factor) { LLRender2D::getInstance()->setScaleFactor(scale_factor); } -	static void setLineWidth(F32 width) { LLRender2D::getInstance()->setLineWidth(width); } +	static void pushMatrix() { LLRender2D::pushMatrix(); } +	static void popMatrix() { LLRender2D::popMatrix(); } +	static void loadIdentity() { LLRender2D::loadIdentity(); } +	static void translate(F32 x, F32 y, F32 z = 0.0f) { LLRender2D::translate(x, y, z); } + +    static LLVector2& getScaleFactor(); +    static void setScaleFactor(const LLVector2& scale_factor); +	static void setLineWidth(F32 width) { LLRender2D::setLineWidth(width); }  	static LLPointer<LLUIImage> getUIImageByID(const LLUUID& image_id, S32 priority = 0)  		{ return LLRender2D::getInstance()->getUIImageByID(image_id, priority); }  	static LLPointer<LLUIImage> getUIImage(const std::string& name, S32 priority = 0) diff --git a/indra/llui/lluictrl.cpp b/indra/llui/lluictrl.cpp index 544a76e8d5..5924542a19 100644 --- a/indra/llui/lluictrl.cpp +++ b/indra/llui/lluictrl.cpp @@ -35,6 +35,7 @@  #include "lluictrlfactory.h"  #include "lltabcontainer.h"  #include "llaccordionctrltab.h" +#include "lluiusage.h"  static LLDefaultChildRegistry::Register<LLUICtrl> r("ui_ctrl"); @@ -282,6 +283,7 @@ LLUICtrl::commit_signal_t::slot_type LLUICtrl::initCommitCallback(const CommitCa  	else  	{  		std::string function_name = cb.function_name; +		setFunctionName(function_name);  		commit_callback_t* func = (CommitCallbackRegistry::getValue(function_name));  		if (func)  		{ @@ -422,7 +424,19 @@ BOOL LLUICtrl::canFocusChildren() const  void LLUICtrl::onCommit()  {  	if (mCommitSignal) -	(*mCommitSignal)(this, getValue()); +	{ +		if (!mFunctionName.empty()) +		{ +			LL_DEBUGS("UIUsage") << "calling commit function " << mFunctionName << LL_ENDL; +			LLUIUsage::instance().logCommand(mFunctionName); +			LLUIUsage::instance().logControl(getPathname()); +		} +		else +		{ +			//LL_DEBUGS("UIUsage") << "calling commit function " << "UNKNOWN" << LL_ENDL; +		} +		(*mCommitSignal)(this, getValue()); +	}  }  //virtual @@ -597,6 +611,12 @@ void LLUICtrl::setMakeInvisibleControlVariable(LLControlVariable* control)  		setVisible(!(mMakeInvisibleControlVariable->getValue().asBoolean()));  	}  } + +void LLUICtrl::setFunctionName(const std::string& function_name) +{ +	mFunctionName = function_name; +} +  // static  bool LLUICtrl::controlListener(const LLSD& newvalue, LLHandle<LLUICtrl> handle, std::string type)  { diff --git a/indra/llui/lluictrl.h b/indra/llui/lluictrl.h index 7360bd7659..67dd24341c 100644 --- a/indra/llui/lluictrl.h +++ b/indra/llui/lluictrl.h @@ -183,6 +183,8 @@ public:  	void setMakeVisibleControlVariable(LLControlVariable* control);  	void setMakeInvisibleControlVariable(LLControlVariable* control); +	void setFunctionName(const std::string& function_name); +	  	virtual void	setTentative(BOOL b);  	virtual BOOL	getTentative() const;  	virtual void	setValue(const LLSD& value); @@ -310,6 +312,8 @@ protected:  	LLControlVariable* mMakeInvisibleControlVariable;  	boost::signals2::connection mMakeInvisibleControlConnection; +	std::string mFunctionName; +  	static F32 sActiveControlTransparency;  	static F32 sInactiveControlTransparency; diff --git a/indra/llui/lluiusage.cpp b/indra/llui/lluiusage.cpp new file mode 100644 index 0000000000..ccae6643b9 --- /dev/null +++ b/indra/llui/lluiusage.cpp @@ -0,0 +1,146 @@ +/** +* @file lluiuisage.cpp +* @brief Source file for LLUIUsage +* +* $LicenseInfo:firstyear=2021&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2021, 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 "lluiusage.h" +#include <boost/algorithm/string.hpp> + +LLUIUsage::LLUIUsage() +{ +} + +LLUIUsage::~LLUIUsage() +{ +} + +// static +std::string LLUIUsage::sanitized(const std::string& s) +{ +	// Remove characters that make the ViewerStats db unhappy +	std::string result(s); +	std::replace(result.begin(), result.end(), '.', '_'); +	std::replace(result.begin(), result.end(), ' ', '_'); +	return result; +} + +// static +void LLUIUsage::setLLSDPath(LLSD& sd, const std::string& path, S32 max_elts, const LLSD& val) +{ +	// Keep the last max_elts components of the specified path +	std::vector<std::string> fields; +	boost::split(fields, path, boost::is_any_of("/")); +	auto first_pos = std::max(fields.begin(), fields.end() - max_elts); +	auto end_pos = fields.end(); +	std::vector<std::string> last_fields(first_pos,end_pos); + +	setLLSDNested(sd, last_fields, val); +} + +// setLLSDNested() +// Accomplish the equivalent of  +//   sd[fields[0]][fields[1]]... = val; +// for an arbitrary number of fields. +// This might be useful as an LLSD utility function; is not specific to LLUIUsage +//  +// static +void LLUIUsage::setLLSDNested(LLSD& sd, const std::vector<std::string>& fields, const LLSD& val) +{ +	LLSD* fsd = &sd; +	for (auto it=fields.begin(); it!=fields.end(); ++it) +	{ +		if (it == fields.end()-1) +		{ +			(*fsd)[*it] = val; +		} +		else +		{ +			if (!(*fsd)[*it].isMap()) +			{ +				(*fsd)[*it] = LLSD::emptyMap(); +			} +			fsd = &(*fsd)[*it]; +		} +	} +} + +void LLUIUsage::logCommand(const std::string& command) +{ +	mCommandCounts[sanitized(command)]++; +	LL_DEBUGS("UIUsage") << "command " << command << LL_ENDL; +} + +void LLUIUsage::logControl(const std::string& control) +{ +	mControlCounts[sanitized(control)]++; +	LL_DEBUGS("UIUsage") << "control " << control << LL_ENDL; +} + + +void LLUIUsage::logFloater(const std::string& floater) +{ +	mFloaterCounts[sanitized(floater)]++; +	LL_DEBUGS("UIUsage") << "floater " << floater << LL_ENDL; +} + +void LLUIUsage::logPanel(const std::string& p) +{ +	mPanelCounts[sanitized(p)]++; +	LL_DEBUGS("UIUsage") << "panel " << p << LL_ENDL; +} + +LLSD LLUIUsage::asLLSD() const +{ +	LLSD result; +	for (auto const& it : mCommandCounts) +	{ +		result["commands"][it.first] = LLSD::Integer(it.second); +	} +	for (auto const& it : mControlCounts) +	{ +		setLLSDPath(result["controls"], it.first, 2, LLSD::Integer(it.second)); +	} +	for (auto const& it : mFloaterCounts) +	{ +		result["floaters"][it.first] = LLSD::Integer(it.second); +	} +	for (auto const& it : mPanelCounts) +	{ +		result["panels"][it.first] = LLSD::Integer(it.second); +	} +	return result; +} + +// Clear up some junk content generated during initial login/UI initialization +void LLUIUsage::clear() +{ + +	LL_DEBUGS("UIUsage") << "clear" << LL_ENDL; +	mCommandCounts.clear(); +	mControlCounts.clear(); +	mFloaterCounts.clear(); +	mPanelCounts.clear(); +} + diff --git a/indra/llui/lluiusage.h b/indra/llui/lluiusage.h new file mode 100644 index 0000000000..a30cd80db3 --- /dev/null +++ b/indra/llui/lluiusage.h @@ -0,0 +1,57 @@ +/** +* @file lluiuisage.h +* @brief Header file for LLUIUsage +* +* $LicenseInfo:firstyear=2021&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2021, 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_LLUIUSAGE_H +#define LL_LLUIUSAGE_H + +#include <map> +#include "llsd.h" +#include "llsingleton.h" + +// UIUsage tracking to see which operations and UI elements are most popular in a session +class LLUIUsage : public LLSingleton<LLUIUsage> +{ +public: +	LLSINGLETON(LLUIUsage); +	~LLUIUsage(); +public: +	static std::string sanitized(const std::string& s); +	static void setLLSDPath(LLSD& sd, const std::string& path, S32 max_elts, const LLSD& val); +	static void setLLSDNested(LLSD& sd, const std::vector<std::string>& fields, const LLSD& val); +	void logCommand(const std::string& command); +	void logControl(const std::string& control); +	void logFloater(const std::string& floater); +	void logPanel(const std::string& p); +	LLSD asLLSD() const; +	void clear(); +private: +	std::map<std::string,U32> mCommandCounts; +	std::map<std::string,U32> mControlCounts; +	std::map<std::string,U32> mFloaterCounts; +	std::map<std::string,U32> mPanelCounts; +}; + +#endif // LLUIUIUSAGE.h diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp index 20dda54771..e43c52c0c2 100644 --- a/indra/llui/llurlentry.cpp +++ b/indra/llui/llurlentry.cpp @@ -176,7 +176,7 @@ void LLUrlEntryBase::callObservers(const std::string &id,  bool LLUrlEntryBase::isLinkDisabled() const  {  	// this allows us to have a global setting to turn off text hyperlink highlighting/action -	bool globally_disabled = LLUI::getInstance()->mSettingGroups["config"]->getBOOL("DisableTextHyperlinkActions"); +	static LLCachedControl<bool> globally_disabled(*LLUI::getInstance()->mSettingGroups["config"], "DisableTextHyperlinkActions", false);  	return globally_disabled;  } @@ -464,7 +464,9 @@ LLUrlEntrySecondlifeURL::LLUrlEntrySecondlifeURL()  							"|"  							"(https://([-\\w\\.]*\\.)?(secondlife|lindenlab|tilia-inc)\\.com(:\\d{1,5})?)"  							"|" -							"(https://([-\\w\\.]*\\.)?secondlifegrid\\.net(:\\d{1,5})?))" +							"(https://([-\\w\\.]*\\.)?secondlifegrid\\.net(:\\d{1,5})?)" +							"|" +							"(https?://([-\\w\\.]*\\.)?secondlife\\.io(:\\d{1,5})?))"  							"\\/\\S*",  		boost::regex::perl|boost::regex::icase); @@ -1127,7 +1129,7 @@ std::string LLUrlEntryPlace::getLocation(const std::string &url) const  //  LLUrlEntryRegion::LLUrlEntryRegion()  { -	mPattern = boost::regex("secondlife:///app/region/[^/\\s]+(/\\d+)?(/\\d+)?(/\\d+)?/?", +	mPattern = boost::regex("secondlife:///app/region/[A-Za-z0-9()_%]+(/\\d+)?(/\\d+)?(/\\d+)?/?",  							boost::regex::perl|boost::regex::icase);  	mMenuName = "menu_url_slurl.xml";  	mTooltip = LLTrans::getString("TooltipSLURL"); diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp index cd47e2ecea..b942be2a4a 100644 --- a/indra/llui/llview.cpp +++ b/indra/llui/llview.cpp @@ -60,6 +60,8 @@ static const S32 LINE_HEIGHT = 15;  S32		LLView::sDepth = 0;  bool	LLView::sDebugRects = false; +bool	LLView::sIsRectDirty = false; +LLRect	LLView::sDirtyRect;  bool	LLView::sDebugRectsShowNames = true;  bool	LLView::sDebugKeys = false;  bool	LLView::sDebugMouseHandling = false; @@ -885,14 +887,16 @@ BOOL LLView::handleToolTip(S32 x, S32 y, MASK mask)  	std::string tooltip = getToolTip();  	if (!tooltip.empty())  	{ +        static LLCachedControl<F32> tooltip_fast_delay(*LLUI::getInstance()->mSettingGroups["config"], "ToolTipFastDelay", 0.1f); +        static LLCachedControl<F32> tooltip_delay(*LLUI::getInstance()->mSettingGroups["config"], "ToolTipDelay", 0.7f); +        static LLCachedControl<bool> allow_ui_tooltips(*LLUI::getInstance()->mSettingGroups["config"], "BasicUITooltips", true);  		// allow "scrubbing" over ui by showing next tooltip immediately  		// if previous one was still visible  		F32 timeout = LLToolTipMgr::instance().toolTipVisible()  -		              ? LLUI::getInstance()->mSettingGroups["config"]->getF32( "ToolTipFastDelay" ) -		              : LLUI::getInstance()->mSettingGroups["config"]->getF32( "ToolTipDelay" ); +		              ? tooltip_fast_delay +		              : tooltip_delay;  		// Even if we don't show tooltips, consume the event, nothing below should show tooltip -		bool allow_ui_tooltips = LLUI::getInstance()->mSettingGroups["config"]->getBOOL("BasicUITooltips");  		if (allow_ui_tooltips)  		{  			LLToolTipMgr::instance().show(LLToolTip::Params() @@ -1189,7 +1193,7 @@ void LLView::drawChildren()  			if (viewp->getVisible() && viewp->getRect().isValid())  			{  				LLRect screen_rect = viewp->calcScreenRect(); -				if ( rootp->getLocalRect().overlaps(screen_rect)  && LLUI::getInstance()->mDirtyRect.overlaps(screen_rect)) +				if ( rootp->getLocalRect().overlaps(screen_rect)  && sDirtyRect.overlaps(screen_rect))  				{  					LLUI::pushMatrix();  					{ @@ -1231,7 +1235,15 @@ void LLView::dirtyRect()  		parent = parent->getParent();  	} -	LLUI::getInstance()->dirtyRect(cur->calcScreenRect()); +    if (!sIsRectDirty) +    { +        sDirtyRect = cur->calcScreenRect(); +        sIsRectDirty = true; +    } +    else +    { +        sDirtyRect.unionWith(cur->calcScreenRect()); +    }  }  //Draw a box for debugging. diff --git a/indra/llui/llview.h b/indra/llui/llview.h index 5c91c37d3c..c60dcf3344 100644 --- a/indra/llui/llview.h +++ b/indra/llui/llview.h @@ -657,6 +657,9 @@ public:  	// Draw debug rectangles around widgets to help with alignment and spacing  	static bool	sDebugRects; +    static bool sIsRectDirty; +    static LLRect sDirtyRect; +  	// Draw widget names and sizes when drawing debug rectangles, turning this  	// off is useful to make the rectangles themselves easier to see.  	static bool sDebugRectsShowNames; diff --git a/indra/llui/llvirtualtrackball.cpp b/indra/llui/llvirtualtrackball.cpp index 723643dd25..6e0aef740d 100644 --- a/indra/llui/llvirtualtrackball.cpp +++ b/indra/llui/llvirtualtrackball.cpp @@ -348,6 +348,42 @@ LLQuaternion LLVirtualTrackball::getRotation() const  	return mValue;  } +// static +void LLVirtualTrackball::getAzimuthAndElevation(const LLQuaternion &quat, F32 &azimuth, F32 &elevation) +{ +    // LLQuaternion has own function to get azimuth, but it doesn't appear to return correct values (meant for 2d?) +    LLVector3 point = VectorZero * quat; + +    if (!is_approx_zero(point.mV[VX]) || !is_approx_zero(point.mV[VY])) +    { +        azimuth = atan2f(point.mV[VX], point.mV[VY]); +    } +    else +    { +        azimuth = 0; +    } + +    azimuth -= F_PI_BY_TWO; + +    if (azimuth < 0) +    { +        azimuth += F_PI * 2; +    } + +    // while vector is '1', F32 is not sufficiently precise and we can get +    // values like 1.0000012 which will result in -90deg angle instead of 90deg +    F32 z = llclamp(point.mV[VZ], -1.f, 1.f); +    elevation = asin(z); // because VectorZero's length is '1' +} + +// static +void LLVirtualTrackball::getAzimuthAndElevationDeg(const LLQuaternion &quat, F32 &azimuth, F32 &elevation) +{ +    getAzimuthAndElevation(quat, azimuth, elevation); +    azimuth *= RAD_TO_DEG; +    elevation *= RAD_TO_DEG; +} +  BOOL LLVirtualTrackball::handleHover(S32 x, S32 y, MASK mask)  {      if (hasMouseCapture()) @@ -409,6 +445,10 @@ BOOL LLVirtualTrackball::handleHover(S32 x, S32 y, MASK mask)              mValue *= az_quat;          } +        // we are doing a lot of F32 mathematical operations with loss of precision, +        // re-normalize to compensate +        mValue.normalize(); +          mPrevX = x;          mPrevY = y;          onCommit(); diff --git a/indra/llui/llvirtualtrackball.h b/indra/llui/llvirtualtrackball.h index 2d4b1ece17..c7a893877b 100644 --- a/indra/llui/llvirtualtrackball.h +++ b/indra/llui/llvirtualtrackball.h @@ -96,6 +96,9 @@ public:      void            setRotation(const LLQuaternion &value);      LLQuaternion    getRotation() const; +    static void             getAzimuthAndElevation(const LLQuaternion &quat, F32 &azimuth, F32 &elevation); +    static void             getAzimuthAndElevationDeg(const LLQuaternion &quat, F32 &azimuth, F32 &elevation); +  protected:      friend class LLUICtrlFactory;      LLVirtualTrackball(const Params&); diff --git a/indra/llui/tests/llurlentry_test.cpp b/indra/llui/tests/llurlentry_test.cpp index 4a4fdb72e3..1a474cca90 100644 --- a/indra/llui/tests/llurlentry_test.cpp +++ b/indra/llui/tests/llurlentry_test.cpp @@ -739,11 +739,6 @@ namespace tut  				  "XXX secondlife:///app/region/Burning%20Life%20(Hyper)/27/210/30 XXX",  				  "secondlife:///app/region/Burning%20Life%20(Hyper)/27/210/30"); -		// DEV-35459: SLURLs and teleport Links not parsed properly -		testRegex("Region with quote", url, -				  "XXX secondlife:///app/region/A'ksha%20Oasis/41/166/701 XXX", -			          "secondlife:///app/region/A%27ksha%20Oasis/41/166/701"); -  		// Rendering tests.  		testLabel("Render /app/region/Ahern/50/50/50/", url,  			"secondlife:///app/region/Ahern/50/50/50/", diff --git a/indra/mac_crash_logger/README.txt b/indra/mac_crash_logger/README.txt new file mode 100644 index 0000000000..6932a8d9c3 --- /dev/null +++ b/indra/mac_crash_logger/README.txt @@ -0,0 +1,3 @@ +This component is no longer used in Linden Lab builds. +Change requests to support continued use by open source +builds are welcome. diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 5a33008cf8..22d44f08d0 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -8,9 +8,7 @@ include(00-Common)  include(Linking)  include(Boost) -if (BUGSPLAT_DB) -  include(bugsplat) -endif (BUGSPLAT_DB) +include(bugsplat)  include(BuildPackagesInfo)  include(BuildVersion)  include(CMakeCopyIfDifferent) @@ -96,18 +94,18 @@ include_directories(      ${CMAKE_CURRENT_SOURCE_DIR}      ) -if (BUGSPLAT_DB) -  include_directories( -    ${BUGSPLAT_INCLUDE_DIR} -    ) -endif (BUGSPLAT_DB) -  include_directories(SYSTEM      ${LLCOMMON_SYSTEM_INCLUDE_DIRS}      ${LLXML_SYSTEM_INCLUDE_DIRS}      ${LLPHYSICSEXTENSIONS_INCLUDE_DIRS}      ) +if (USE_BUGSPLAT) +  include_directories(AFTER +    ${BUGSPLAT_INCLUDE_DIR} +    ) +endif (USE_BUGSPLAT) +  set(viewer_SOURCE_FILES      groupchatlistener.cpp      llaccountingcostmanager.cpp @@ -209,6 +207,7 @@ set(viewer_SOURCE_FILES      llflexibleobject.cpp      llfloaterabout.cpp      llfloaterbvhpreview.cpp +    llfloateraddpaymentmethod.cpp      llfloaterauction.cpp      llfloaterautoreplacesettings.cpp      llfloateravatar.cpp @@ -232,6 +231,7 @@ set(viewer_SOURCE_FILES      llfloatercolorpicker.cpp      llfloaterconversationlog.cpp      llfloaterconversationpreview.cpp +    llfloatercreatelandmark.cpp      llfloaterdeleteprefpreset.cpp      llfloaterdestinations.cpp      llfloaterdisplayname.cpp @@ -255,6 +255,7 @@ set(viewer_SOURCE_FILES      llfloaterhandler.cpp      llfloaterhelpbrowser.cpp      llfloaterhoverheight.cpp +    llfloaterhowto.cpp      llfloaterhud.cpp      llfloaterimagepreview.cpp      llfloaterimsessiontab.cpp @@ -637,6 +638,7 @@ set(viewer_SOURCE_FILES      llurl.cpp      llurldispatcher.cpp      llurldispatcherlistener.cpp +    llurlfloaterdispatchhandler.cpp      llurlhistory.cpp      llurllineeditorctrl.cpp      llurlwhitelist.cpp @@ -846,6 +848,7 @@ set(viewer_HEADER_FILES      llflexibleobject.h      llfloaterabout.h      llfloaterbvhpreview.h +    llfloateraddpaymentmethod.h      llfloaterauction.h      llfloaterautoreplacesettings.h      llfloateravatar.h @@ -869,6 +872,7 @@ set(viewer_HEADER_FILES      llfloatercolorpicker.h      llfloaterconversationlog.h      llfloaterconversationpreview.h +    llfloatercreatelandmark.h      llfloaterdeleteprefpreset.h      llfloaterdestinations.h      llfloaterdisplayname.h @@ -892,6 +896,7 @@ set(viewer_HEADER_FILES      llfloaterhandler.h      llfloaterhelpbrowser.h      llfloaterhoverheight.h +    llfloaterhowto.h      llfloaterhud.h      llfloaterimagepreview.h      llfloaterimnearbychat.h @@ -1267,6 +1272,7 @@ set(viewer_HEADER_FILES      llurl.h      llurldispatcher.h      llurldispatcherlistener.h +    llurlfloaterdispatchhandler.h      llurlhistory.h      llurllineeditorctrl.h      llurlwhitelist.h @@ -1419,11 +1425,11 @@ if (DARWIN)      ${COREAUDIO_LIBRARY}      ) -  if (BUGSPLAT_DB) +  if (USE_BUGSPLAT)      list(APPEND viewer_LIBRARIES        ${BUGSPLAT_LIBRARIES}        ) -  endif (BUGSPLAT_DB) +  endif (USE_BUGSPLAT)    # Add resource files to the project.    set(viewer_RESOURCE_FILES @@ -1761,10 +1767,10 @@ if (SDL_FOUND)      )  endif (SDL_FOUND) -if (BUGSPLAT_DB) +if (USE_BUGSPLAT)    set_property(TARGET ${VIEWER_BINARY_NAME} -    PROPERTY COMPILE_DEFINITIONS "LL_BUGSPLAT") -endif (BUGSPLAT_DB) +    PROPERTY COMPILE_DEFINITIONS "${BUGSPLAT_DEFINE}") +endif (USE_BUGSPLAT)  # add package files  file(GLOB EVENT_HOST_SCRIPT_GLOB_LIST @@ -1843,9 +1849,12 @@ if (WINDOWS)        media_plugin_libvlc        media_plugin_example        winmm_shim -      windows-crash-logger        ) +    if (NOT USE_BUGSPLAT) +        LIST(APPEND COPY_INPUT_DEPENDENCIES windows-crash-logger) +    endif (NOT USE_BUGSPLAT) +      if (ADDRESS_SIZE EQUAL 64)          list(APPEND COPY_INPUT_DEPENDENCIES              ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/vivoxsdk_x64.dll @@ -1908,10 +1917,11 @@ if (WINDOWS)        add_dependencies(${VIEWER_BINARY_NAME} copy_win_scripts)      endif (EXISTS ${CMAKE_SOURCE_DIR}/copy_win_scripts) -    add_dependencies(${VIEWER_BINARY_NAME} -      SLPlugin -      windows-crash-logger -    ) +    add_dependencies(${VIEWER_BINARY_NAME} SLPlugin) + +    if (NOT USE_BUGSPLAT) +        add_dependencies(${VIEWER_BINARY_NAME} windows-crash-logger) +    endif (NOT USE_BUGSPLAT)      # sets the 'working directory' for debugging from visual studio.      # Condition for version can be moved to requirements once build agents will be updated (see TOOL-3865) @@ -2063,11 +2073,11 @@ target_link_libraries(${VIEWER_BINARY_NAME}      ${LLAPPEARANCE_LIBRARIES}      ) -if (BUGSPLAT_DB) +if (USE_BUGSPLAT)    target_link_libraries(${VIEWER_BINARY_NAME}      ${BUGSPLAT_LIBRARIES}      ) -endif (BUGSPLAT_DB) +endif (USE_BUGSPLAT)  set(ARTWORK_DIR ${CMAKE_CURRENT_SOURCE_DIR} CACHE PATH      "Path to artwork files.") @@ -2078,13 +2088,16 @@ if (LINUX)    # These are the generated targets that are copied to package/    set(COPY_INPUT_DEPENDENCIES      ${VIEWER_BINARY_NAME} -    linux-crash-logger      SLPlugin      media_plugin_gstreamer010      media_plugin_libvlc      llcommon      ) +  if (NOT USE_BUGSPLAT) +      LIST(APPEND COPY_INPUT_DEPENDENCIES linux-crash-logger) +  endif (NOT USE_BUGSPLAT) +    add_custom_command(        OUTPUT ${product}.tar.bz2        COMMAND ${PYTHON_EXECUTABLE} @@ -2215,8 +2228,11 @@ if (DARWIN)        ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py      ) -  add_dependencies(${VIEWER_BINARY_NAME} SLPlugin media_plugin_libvlc media_plugin_cef mac-crash-logger) -  add_dependencies(${VIEWER_BINARY_NAME} mac-crash-logger) +  add_dependencies(${VIEWER_BINARY_NAME} SLPlugin media_plugin_libvlc media_plugin_cef) + +  if (NOT USE_BUGSPLAT) +      add_dependencies(${VIEWER_BINARY_NAME} mac-crash-logger) +  endif (NOT USE_BUGSPLAT)    if (ENABLE_SIGNING)        set(SIGNING_SETTING "--signature=${SIGNING_IDENTITY}") @@ -2259,7 +2275,7 @@ endif (INSTALL)  # Note that the conventional VIEWER_SYMBOL_FILE is set by ../../build.sh  if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND VIEWER_SYMBOL_FILE) -  if (NOT BUGSPLAT_DB) +  if (NOT USE_BUGSPLAT)      # Breakpad symbol-file generation      set(SYMBOL_SEARCH_DIRS "")      if (WINDOWS) @@ -2276,7 +2292,7 @@ if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND VIE        list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/llplugin/slplugin/${CMAKE_CFG_INTDIR}")        list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/mac_crash_logger/${CMAKE_CFG_INTDIR}")        list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/media_plugins/gstreamer010/${CMAKE_CFG_INTDIR}") -      set(VIEWER_EXE_GLOBS "'${product}' SLPlugin mac-crash-logger") +      set(VIEWER_EXE_GLOBS "'${product}' SLPlugin")        set(VIEWER_EXE_GLOBS "'${product}' mac-crash-logger")        set(VIEWER_LIB_GLOB "*.dylib")      endif (DARWIN) @@ -2314,7 +2330,7 @@ if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND VIE        add_dependencies(generate_symbols "${VIEWER_COPY_MANIFEST}")      endif (WINDOWS OR LINUX) -  else (NOT BUGSPLAT_DB) +  else (NOT USE_BUGSPLAT)      # BugSplat symbol-file generation      if (WINDOWS)        # Just pack up a tarball containing only the .pdb file for the @@ -2398,9 +2414,9 @@ if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND VIE      if (LINUX)        # TBD      endif (LINUX) -  endif (NOT BUGSPLAT_DB) +  endif (NOT USE_BUGSPLAT) -  # for both BUGSPLAT_DB and Breakpad +  # for both Bugsplat and Breakpad    add_dependencies(llpackage generate_symbols)  endif () @@ -2533,6 +2549,10 @@ if (LL_TESTS)      ${BOOST_CONTEXT_LIBRARY}    ) +  LL_ADD_INTEGRATION_TEST(cppfeatures +    "" +    "${test_libs}" +    )    LL_ADD_INTEGRATION_TEST(llsechandler_basic      llsechandler_basic.cpp      "${test_libs}" diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt index e786022da5..a15225fad6 100644 --- a/indra/newview/VIEWER_VERSION.txt +++ b/indra/newview/VIEWER_VERSION.txt @@ -1 +1 @@ -6.4.20 +6.4.22 diff --git a/indra/newview/app_settings/commands.xml b/indra/newview/app_settings/commands.xml index 22bf2849d5..023ea7c420 100644 --- a/indra/newview/app_settings/commands.xml +++ b/indra/newview/app_settings/commands.xml @@ -88,8 +88,10 @@             icon="Command_HowTo_Icon"             label_ref="Command_HowTo_Label"             tooltip_ref="Command_HowTo_Tooltip" -           execute_function="Help.ToggleHowTo" -           is_running_function="Help.HowToVisible" +           execute_function="Floater.ToggleOrBringToFront" +           execute_parameters="guidebook" +           is_running_function="Floater.IsOpen" +           is_running_parameters="guidebook"             />    <command name="inventory"             available_in_toybox="true" diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 6de3fd04e6..5664ade1a2 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -4725,6 +4725,17 @@        <key>Value</key>        <string>https://search.[GRID]/viewer/[CATEGORY]/?q=[QUERY]&p=[AUTH_TOKEN]&r=[MATURITY]&lang=[LANGUAGE]&g=[GODLIKE]&sid=[SESSION_ID]&rid=[REGION_ID]&pid=[PARCEL_ID]&channel=[CHANNEL]&version=[VERSION]&major=[VERSION_MAJOR]&minor=[VERSION_MINOR]&patch=[VERSION_PATCH]&build=[VERSION_BUILD]</string>      </map> +    <key>GuidebookURL</key> +    <map> +      <key>Comment</key> +      <string>URL for Guidebook content</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>String</string> +      <key>Value</key> +      <string>http://guidebooks.secondlife.io/welcome/index.html</string> +    </map>      <key>HighResSnapshot</key>      <map>        <key>Comment</key> @@ -14324,19 +14335,6 @@        <key>Value</key>        <integer>1</integer>      </map> -    <!-- SL-12594 removes fixed function rendering -    <key>VertexShaderEnable</key> -    <map> -      <key>Comment</key> -      <string>Enable/disable all GLSL shaders (debug)</string> -      <key>Persist</key> -      <integer>1</integer> -      <key>Type</key> -      <string>Boolean</string> -      <key>Value</key> -      <integer>0</integer> -    </map> -    <-->      <key>VivoxAutoPostCrashDumps</key>      <map>        <key>Comment</key> @@ -14425,7 +14423,52 @@        <key>Value</key>        <integer>44125</integer>      </map> -    <key>VoiceCallsFriendsOnly</key> + +  <key>VivoxVadAuto</key> +  <map> +    <key>Comment</key> +    <string>A flag indicating if the automatic VAD is enabled (1) or disabled (0). The individual settings are ignored if the auto-mode is enabled</string> +    <key>Persist</key> +    <integer>1</integer> +    <key>Type</key> +    <string>U32</string> +    <key>Value</key> +    <integer>0</integer> +  </map> +  <key>VivoxVadHangover</key> +  <map> +    <key>Comment</key> +    <string>The time (in milliseconds) that it takes or the VAD to switch back to silence from speech mode after the last speech frame has been detected</string> +    <key>Persist</key> +    <integer>1</integer> +    <key>Type</key> +    <string>U32</string> +    <key>Value</key> +    <integer>2000</integer> +  </map> +  <key>VivoxVadNoiseFloor</key> +  <map> +    <key>Comment</key> +    <string>A dimensionless value between 0 and 20000 (default 576) that controls the maximum level at which the noise floor may be set at by the VAD's noise tracking</string> +    <key>Persist</key> +    <integer>1</integer> +    <key>Type</key> +    <string>U32</string> +    <key>Value</key> +    <integer>576</integer> +  </map> +  <key>VivoxVadSensitivity</key> +  <map> +    <key>Comment</key> +    <string>A dimensionless value between 0 and 100, indicating the 'sensitivity of the VAD'. Increasing this value corresponds to decreasing the sensitivity of the VAD and 0 is turned off altogether</string> +    <key>Persist</key> +    <integer>1</integer> +    <key>Type</key> +    <string>U32</string> +    <key>Value</key> +    <integer>0</integer> +  </map> +  <key>VoiceCallsFriendsOnly</key>      <map>        <key>Comment</key>        <string>(Deprecated) Only accept voice calls from residents on your friends list</string> diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt index e6ee458719..f1bf8d76c2 100644 --- a/indra/newview/featuretable.txt +++ b/indra/newview/featuretable.txt @@ -56,7 +56,6 @@ RenderVBOMappingDisable		1	1  RenderVolumeLODFactor		1	2.0  UseStartScreen				1	1  UseOcclusion				1	1 -VertexShaderEnable			1	1  WindLightUseAtmosShaders	1	1  WLSkyDetail					1	128  Disregard128DefaultDrawDistance	1	1 @@ -95,7 +94,6 @@ RenderTerrainLODFactor		1	1  RenderTransparentWater		1	0  RenderTreeLODFactor			1	0  RenderVolumeLODFactor		1	1.125 -VertexShaderEnable			1	0  WindLightUseAtmosShaders	1	0  RenderDeferred				1	0  RenderDeferredSSAO			1	0 @@ -127,7 +125,6 @@ RenderTerrainLODFactor		1	1  RenderTransparentWater		1	0  RenderTreeLODFactor			1	0  RenderVolumeLODFactor		1	1.125 -VertexShaderEnable			1	1  WindLightUseAtmosShaders	1	0  RenderDeferred				1	0  RenderDeferredSSAO			1	0 @@ -158,7 +155,6 @@ RenderTerrainLODFactor		1	1.0  RenderTransparentWater		1	1  RenderTreeLODFactor			1	0.5  RenderVolumeLODFactor		1	1.125 -VertexShaderEnable			1	1  WindLightUseAtmosShaders	1	0  RenderDeferred				1	0  RenderDeferredSSAO			1	0 @@ -189,7 +185,6 @@ RenderTerrainLODFactor		1	2.0  RenderTransparentWater		1	1  RenderTreeLODFactor			1	0.5  RenderVolumeLODFactor		1	1.125 -VertexShaderEnable			1	1  WindLightUseAtmosShaders	1	1  RenderDeferred				1	0  RenderDeferredSSAO			1	0 @@ -220,7 +215,6 @@ RenderTerrainLODFactor		1	2.0  RenderTransparentWater		1	1  RenderTreeLODFactor			1	0.5  RenderVolumeLODFactor		1	1.125 -VertexShaderEnable			1	1  WindLightUseAtmosShaders	1	1  RenderDeferred				1	1  RenderDeferredSSAO			1	0 @@ -251,7 +245,6 @@ RenderTerrainLODFactor		1	2.0  RenderTransparentWater		1	1  RenderTreeLODFactor			1	0.5  RenderVolumeLODFactor		1	1.125 -VertexShaderEnable			1	1  WindLightUseAtmosShaders	1	1  RenderDeferred				1	1  RenderDeferredSSAO			1	1 @@ -282,7 +275,6 @@ RenderTerrainLODFactor		1	2.0  RenderTransparentWater		1	1  RenderTreeLODFactor			1	0.5  RenderVolumeLODFactor		1	1.125 -VertexShaderEnable			1	1  WindLightUseAtmosShaders	1	1  RenderDeferred				1	1  RenderDeferredSSAO			1	1 @@ -312,7 +304,6 @@ RenderTerrainLODFactor		1	2.0  RenderTransparentWater		1	1  RenderTreeLODFactor			1	1.0  RenderVolumeLODFactor		1	2.0 -VertexShaderEnable			1	1  WindLightUseAtmosShaders	1	1  WLSkyDetail					1	128  RenderDeferred				1	1 @@ -380,7 +371,6 @@ list NoPixelShaders  RenderAvatarVP				0	0  RenderAvatarCloth			0	0  RenderReflectionDetail		0	0 -VertexShaderEnable			0	0  WindLightUseAtmosShaders	0	0  RenderDeferred				0	0  RenderDeferredSSAO			0	0 @@ -394,7 +384,6 @@ list NoVertexShaders  RenderAvatarVP				0	0  RenderAvatarCloth			0	0  RenderReflectionDetail		0	0 -VertexShaderEnable			0	0  WindLightUseAtmosShaders	0	0  RenderDeferred				0	0  RenderDeferredSSAO			0	0 diff --git a/indra/newview/featuretable_linux.txt b/indra/newview/featuretable_linux.txt index bc836a99ca..5542eee6ca 100644 --- a/indra/newview/featuretable_linux.txt +++ b/indra/newview/featuretable_linux.txt @@ -56,7 +56,6 @@ RenderVBOMappingDisable		1	1  RenderVolumeLODFactor		1	2.0  UseStartScreen				1	1  UseOcclusion				1	1 -VertexShaderEnable			1	1  WindLightUseAtmosShaders	1	1  WLSkyDetail					1	128  Disregard128DefaultDrawDistance	1	1 @@ -94,7 +93,6 @@ RenderTerrainLODFactor		1	1  RenderTransparentWater		1	0  RenderTreeLODFactor			1	0  RenderVolumeLODFactor		1	1.125 -VertexShaderEnable			1	1  WindLightUseAtmosShaders	1	0  RenderDeferred				1	0  RenderDeferredSSAO			1	0 @@ -126,7 +124,6 @@ RenderTerrainLODFactor		1	1  RenderTransparentWater		1	0  RenderTreeLODFactor			1	0  RenderVolumeLODFactor		1	1.125 -VertexShaderEnable			1	0  WindLightUseAtmosShaders	1	0  RenderDeferred				1	0  RenderDeferredSSAO			1	0 @@ -157,7 +154,6 @@ RenderTerrainLODFactor		1	1.0  RenderTransparentWater		1	1  RenderTreeLODFactor			1	0.5  RenderVolumeLODFactor		1	1.125 -VertexShaderEnable			1	1  WindLightUseAtmosShaders	1	0  RenderDeferred				1	0  RenderDeferredSSAO			1	0 @@ -188,7 +184,6 @@ RenderTerrainLODFactor		1	2.0  RenderTransparentWater		1	1  RenderTreeLODFactor			1	0.5  RenderVolumeLODFactor		1	1.125 -VertexShaderEnable			1	1  WindLightUseAtmosShaders	1	1  RenderDeferred				1	0  RenderDeferredSSAO			1	0 @@ -219,7 +214,6 @@ RenderTerrainLODFactor		1	2.0  RenderTransparentWater		1	1  RenderTreeLODFactor			1	0.5  RenderVolumeLODFactor		1	1.125 -VertexShaderEnable			1	1  WindLightUseAtmosShaders	1	1  RenderDeferred				1	1  RenderUseAdvancedAtmospherics 1 0 @@ -250,7 +244,6 @@ RenderTerrainLODFactor		1	2.0  RenderTransparentWater		1	1  RenderTreeLODFactor			1	0.5  RenderVolumeLODFactor		1	1.125 -VertexShaderEnable			1	1  WindLightUseAtmosShaders	1	1  RenderDeferred				1	1  RenderDeferredSSAO			1	1 @@ -281,7 +274,6 @@ RenderTerrainLODFactor		1	2.0  RenderTransparentWater		1	1  RenderTreeLODFactor			1	0.5  RenderVolumeLODFactor		1	1.125 -VertexShaderEnable			1	1  WindLightUseAtmosShaders	1	1  RenderDeferred				1	1  RenderDeferredSSAO			1	1 @@ -311,7 +303,6 @@ RenderTerrainLODFactor		1	2.0  RenderTransparentWater		1	1  RenderTreeLODFactor			1	1.0  RenderVolumeLODFactor		1	2.0 -VertexShaderEnable			1	1  WindLightUseAtmosShaders	1	1  WLSkyDetail					1	128  RenderDeferred				1	1 @@ -379,7 +370,6 @@ list NoPixelShaders  RenderAvatarVP				0	0  RenderAvatarCloth			0	0  RenderReflectionDetail		0	0 -VertexShaderEnable			0	0  WindLightUseAtmosShaders	0	0  RenderDeferred				0	0  RenderDeferredSSAO			0	0 @@ -393,7 +383,6 @@ list NoVertexShaders  RenderAvatarVP				0	0  RenderAvatarCloth			0	0  RenderReflectionDetail		0	0 -VertexShaderEnable			0	0  WindLightUseAtmosShaders	0	0  RenderDeferred				0	0  RenderDeferredSSAO			0	0 diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt index 68202a571f..bac6fd5708 100644 --- a/indra/newview/featuretable_mac.txt +++ b/indra/newview/featuretable_mac.txt @@ -56,7 +56,6 @@ RenderVBOMappingDisable		1	1  RenderVolumeLODFactor		1	2.0  UseStartScreen				1	1  UseOcclusion				1	1 -VertexShaderEnable			1	1  WindLightUseAtmosShaders	1	1  WLSkyDetail					1	128  Disregard128DefaultDrawDistance	1	1 @@ -95,7 +94,6 @@ RenderTerrainLODFactor		1	1  RenderTransparentWater		1	0  RenderTreeLODFactor			1	0  RenderVolumeLODFactor		1	0.5 -VertexShaderEnable			1	0  WindLightUseAtmosShaders	1	0  RenderDeferred				1	0  RenderDeferredSSAO			1	0 @@ -127,7 +125,6 @@ RenderTerrainLODFactor		1	1  RenderTransparentWater		1	0  RenderTreeLODFactor			1	0  RenderVolumeLODFactor		1	0.5 -VertexShaderEnable			1	1  WindLightUseAtmosShaders	1	0  RenderDeferred				1	0  RenderDeferredSSAO			1	0 @@ -158,7 +155,6 @@ RenderTerrainLODFactor		1	1.0  RenderTransparentWater		1	1  RenderTreeLODFactor			1	0.5  RenderVolumeLODFactor		1	1.125 -VertexShaderEnable			1	1  WindLightUseAtmosShaders	1	0  RenderDeferred				1	0  RenderDeferredSSAO			1	0 @@ -189,7 +185,6 @@ RenderTerrainLODFactor		1	2.0  RenderTransparentWater		1	1  RenderTreeLODFactor			1	0.5  RenderVolumeLODFactor		1	1.125 -VertexShaderEnable			1	1  WindLightUseAtmosShaders	1	1  RenderDeferred				1	0  RenderDeferredSSAO			1	0 @@ -220,7 +215,6 @@ RenderTerrainLODFactor		1	2.0  RenderTransparentWater		1	1  RenderTreeLODFactor			1	0.5  RenderVolumeLODFactor		1	1.125 -VertexShaderEnable			1	1  WindLightUseAtmosShaders	1	1  RenderDeferred				1	1  RenderDeferredSSAO			1	0 @@ -251,7 +245,6 @@ RenderTerrainLODFactor		1	2.0  RenderTransparentWater		1	1  RenderTreeLODFactor			1	0.5  RenderVolumeLODFactor		1	1.125 -VertexShaderEnable			1	1  WindLightUseAtmosShaders	1	1  RenderDeferred				1	1  RenderDeferredSSAO			1	1 @@ -282,7 +275,6 @@ RenderTerrainLODFactor		1	2.0  RenderTransparentWater		1	1  RenderTreeLODFactor			1	0.5  RenderVolumeLODFactor		1	1.125 -VertexShaderEnable			1	1  WindLightUseAtmosShaders	1	1  RenderDeferred				1	1  RenderDeferredSSAO			1	1 @@ -312,7 +304,6 @@ RenderTerrainLODFactor		1	2.0  RenderTransparentWater		1	1  RenderTreeLODFactor			1	1.0  RenderVolumeLODFactor		1	2.0 -VertexShaderEnable			1	1  WindLightUseAtmosShaders	1	1  WLSkyDetail					1	128  RenderDeferred				1	1 @@ -374,7 +365,6 @@ list NoPixelShaders  RenderAvatarVP				0	0  RenderAvatarCloth			0	0  RenderReflectionDetail		0	0 -VertexShaderEnable			0	0  WindLightUseAtmosShaders	0	0  RenderDeferred				0	0  RenderDeferredSSAO			0	0 @@ -388,7 +378,6 @@ list NoVertexShaders  RenderAvatarVP				0	0  RenderAvatarCloth			0	0  RenderReflectionDetail		0	0 -VertexShaderEnable			0	0  WindLightUseAtmosShaders	0	0  RenderDeferred				0	0  RenderDeferredSSAO			0	0 diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index c65bc0fa50..389448654a 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -108,7 +108,8 @@ const U8 AGENT_STATE_EDITING =  0x10;  // Autopilot constants  const F32 AUTOPILOT_HEIGHT_ADJUST_DISTANCE = 8.f;			// meters  const F32 AUTOPILOT_MIN_TARGET_HEIGHT_OFF_GROUND = 1.f;	// meters -const F32 AUTOPILOT_MAX_TIME_NO_PROGRESS = 1.5f;		// seconds +const F32 AUTOPILOT_MAX_TIME_NO_PROGRESS_WALK = 1.5f;		// seconds +const F32 AUTOPILOT_MAX_TIME_NO_PROGRESS_FLY = 2.5f;		// seconds. Flying is less presize, needs a bit more time  const F32 MAX_VELOCITY_AUTO_LAND_SQUARED = 4.f * 4.f;  const F64 CHAT_AGE_FAST_RATE = 3.0; @@ -387,6 +388,7 @@ LLAgent::LLAgent() :  	mTeleportFinishedSlot(),  	mTeleportFailedSlot(),  	mIsMaturityRatingChangingDuringTeleport(false), +	mTPNeedsNeabyChatSeparator(false),  	mMaturityRatingChange(0U),  	mIsDoSendMaturityPreferenceToServer(false),  	mMaturityPreferenceRequestId(0U), @@ -878,13 +880,12 @@ boost::signals2::connection LLAgent::addParcelChangedCallback(parcel_changed_cal  }  // static -void LLAgent::capabilityReceivedCallback(const LLUUID ®ion_id) +void LLAgent::capabilityReceivedCallback(const LLUUID ®ion_id, LLViewerRegion *regionp)  { -    LLViewerRegion* region = gAgent.getRegion(); -    if (region && region->getRegionID() == region_id) +    if (regionp && regionp->getRegionID() == region_id)      { -        region->requestSimulatorFeatures(); -        LLAppViewer::instance()->updateNameLookupUrl(); +        regionp->requestSimulatorFeatures(); +        LLAppViewer::instance()->updateNameLookupUrl(regionp);      }  } @@ -935,7 +936,7 @@ void LLAgent::setRegion(LLViewerRegion *regionp)              if (regionp->capabilitiesReceived())              {                  regionp->requestSimulatorFeatures(); -                LLAppViewer::instance()->updateNameLookupUrl(); +                LLAppViewer::instance()->updateNameLookupUrl(regionp);              }              else              { @@ -961,11 +962,11 @@ void LLAgent::setRegion(LLViewerRegion *regionp)              if (regionp->capabilitiesReceived())              { -                LLAppViewer::instance()->updateNameLookupUrl(); +                LLAppViewer::instance()->updateNameLookupUrl(regionp);              }              else              { -                regionp->setCapabilitiesReceivedCallback([](const LLUUID ®ion_id) {LLAppViewer::instance()->updateNameLookupUrl(); }); +                regionp->setCapabilitiesReceivedCallback([](const LLUUID ®ion_id, LLViewerRegion* regionp) {LLAppViewer::instance()->updateNameLookupUrl(regionp); });              }  		} @@ -1562,6 +1563,12 @@ void LLAgent::startAutoPilotGlobal(  	{  		return;  	} + +    if (target_global.isExactlyZero()) +    { +        LL_WARNS() << "Canceling attempt to start autopilot towards invalid position" << LL_ENDL; +        return; +    }  	// Are there any pending callbacks from previous auto pilot requests?  	if (mAutoPilotFinishedCallback) @@ -1777,7 +1784,16 @@ void LLAgent::autoPilot(F32 *delta_yaw)  		if (target_dist >= mAutoPilotTargetDist)  		{  			mAutoPilotNoProgressFrameCount++; -			if (mAutoPilotNoProgressFrameCount > AUTOPILOT_MAX_TIME_NO_PROGRESS * gFPSClamped) +            bool out_of_time = false; +            if (getFlying()) +            { +                out_of_time = mAutoPilotNoProgressFrameCount > AUTOPILOT_MAX_TIME_NO_PROGRESS_FLY * gFPSClamped; +            } +            else +            { +                out_of_time = mAutoPilotNoProgressFrameCount > AUTOPILOT_MAX_TIME_NO_PROGRESS_WALK * gFPSClamped; +            } +			if (out_of_time)  			{  				stopAutoPilot();  				return; @@ -1826,7 +1842,7 @@ void LLAgent::autoPilot(F32 *delta_yaw)  		F32 slow_distance;  		if (getFlying())  		{ -			slow_distance = llmax(6.f, mAutoPilotStopDistance + 5.f); +			slow_distance = llmax(8.f, mAutoPilotStopDistance + 5.f);  		}  		else  		{ @@ -1870,14 +1886,41 @@ void LLAgent::autoPilot(F32 *delta_yaw)  		}  		else if (mAutoPilotTargetDist > mAutoPilotStopDistance)  		{ -			// walking/flying slow +            // walking/flying slow +            U32 movement_flag = 0; +  			if (at * direction > 0.9f)  			{ -				setControlFlags(AGENT_CONTROL_AT_POS); -			} -			else if (at * direction < -0.9f) -			{ -				setControlFlags(AGENT_CONTROL_AT_NEG); +                movement_flag = AGENT_CONTROL_AT_POS; +            } +            else if (at * direction < -0.9f) +            { +                movement_flag = AGENT_CONTROL_AT_NEG; +            } + +            if (getFlying()) +            { +                // flying is too fast and has high inertia, artificially slow it down +                // Don't update flags too often, server might not react +                static U64 last_time_microsec = 0; +                U64 time_microsec = LLTimer::getTotalTime(); +                U64 delta = time_microsec - last_time_microsec; +                // fly during ~0-40 ms, stop during ~40-250 ms +                if (delta > 250000) // 250ms +                { +                    // reset even if !movement_flag +                    last_time_microsec = time_microsec; +                } +                else if (delta > 40000) // 40 ms +                { +                    clearControlFlags(AGENT_CONTROL_AT_POS | AGENT_CONTROL_AT_POS); +                    movement_flag = 0; +                } +            } + +            if (movement_flag) +            { +                setControlFlags(movement_flag);  			}  		} @@ -3934,6 +3977,7 @@ void LLAgent::clearTeleportRequest()          LLVoiceClient::getInstance()->setHidden(FALSE);      }  	mTeleportRequest.reset(); +    mTPNeedsNeabyChatSeparator = false;  }  void LLAgent::setMaturityRatingChangeDuringTeleport(U8 pMaturityRatingChange) @@ -3942,6 +3986,12 @@ void LLAgent::setMaturityRatingChangeDuringTeleport(U8 pMaturityRatingChange)  	mMaturityRatingChange = pMaturityRatingChange;  } +void LLAgent::sheduleTeleportIM() +{ +    // is supposed to be called during teleport so we are still waiting for parcel +    mTPNeedsNeabyChatSeparator = true; +} +  bool LLAgent::hasPendingTeleportRequest()  {  	return ((mTeleportRequest != NULL) && @@ -3989,6 +4039,12 @@ void LLAgent::startTeleportRequest()  void LLAgent::handleTeleportFinished()  {      LL_INFOS("Teleport") << "Agent handling teleport finished." << LL_ENDL; +    if (mTPNeedsNeabyChatSeparator) +    { +        // parcel is ready at this point +        addTPNearbyChatSeparator(); +        mTPNeedsNeabyChatSeparator = false; +    }  	clearTeleportRequest();      mTeleportCanceled.reset();  	if (mIsMaturityRatingChangingDuringTeleport) @@ -4051,6 +4107,44 @@ void LLAgent::handleTeleportFailed()  		LLNotificationsUtil::add("PreferredMaturityChanged", args);  		mIsMaturityRatingChangingDuringTeleport = false;  	} + +    mTPNeedsNeabyChatSeparator = false; +} + +/*static*/ +void LLAgent::addTPNearbyChatSeparator() +{ +    LLViewerRegion* agent_region = gAgent.getRegion(); +    LLParcel* agent_parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); +    if (!agent_region || !agent_parcel) +    { +        return; +    } + +    LLFloaterIMNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat"); +    if (nearby_chat) +    { +        std::string location_name; +        LLAgentUI::ELocationFormat format = LLAgentUI::LOCATION_FORMAT_NO_MATURITY; + +        // Might be better to provide slurl to chat +        if (!LLAgentUI::buildLocationString(location_name, format)) +        { +            location_name = "Teleport to new region"; // Shouldn't happen +        } + +        LLChat chat; +        chat.mFromName = location_name; +        chat.mMuted = FALSE; +        chat.mFromID = LLUUID::null; +        chat.mSourceType = CHAT_SOURCE_TELEPORT; +        chat.mChatStyle = CHAT_STYLE_TELEPORT_SEP; +        chat.mText = ""; + +        LLSD args; +        args["do_not_log"] = TRUE; +        nearby_chat->addMessage(chat, true, args); +    }  }  /*static*/ diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h index d46c99db8c..134540c6b3 100644 --- a/indra/newview/llagent.h +++ b/indra/newview/llagent.h @@ -254,7 +254,7 @@ public:  	boost::signals2::connection     addParcelChangedCallback(parcel_changed_callback_t);  private: -	static void capabilityReceivedCallback(const LLUUID ®ion_id); +	static void capabilityReceivedCallback(const LLUUID ®ion_id, LLViewerRegion *regionp);  	typedef boost::signals2::signal<void()> parcel_changed_signal_t;  	parcel_changed_signal_t		mParcelChangedSignal; @@ -653,6 +653,7 @@ public:  	void            restartFailedTeleportRequest();  	void            clearTeleportRequest();  	void            setMaturityRatingChangeDuringTeleport(U8 pMaturityRatingChange); +	void            sheduleTeleportIM();  private: @@ -669,6 +670,7 @@ private:  	boost::signals2::connection mTeleportFailedSlot;  	bool            mIsMaturityRatingChangingDuringTeleport; +	bool            mTPNeedsNeabyChatSeparator;  	U8              mMaturityRatingChange;  	bool            hasPendingTeleportRequest(); @@ -685,6 +687,7 @@ private:  	void            handleTeleportFinished();  	void            handleTeleportFailed(); +    static void     addTPNearbyChatSeparator();      static void     onCapabilitiesReceivedAfterTeleport();  	//-------------------------------------------------------------------- diff --git a/indra/newview/llappcorehttp.cpp b/indra/newview/llappcorehttp.cpp index 134a34137b..3da87e657c 100644 --- a/indra/newview/llappcorehttp.cpp +++ b/indra/newview/llappcorehttp.cpp @@ -116,6 +116,7 @@ static const struct  };  static void setting_changed(); +static void ssl_verification_changed();  LLAppCoreHttp::HttpClass::HttpClass() @@ -195,6 +196,23 @@ void LLAppCoreHttp::init()  		LL_WARNS("Init") << "Failed to set SSL Verification.  Reason:  " << status.toString() << LL_ENDL;  	} +    // Set up Default SSL Verification option. +    const std::string no_verify_ssl("NoVerifySSLCert"); +    if (gSavedSettings.controlExists(no_verify_ssl)) +    { +        LLPointer<LLControlVariable> cntrl_ptr = gSavedSettings.getControl(no_verify_ssl); +        if (cntrl_ptr.isNull()) +        { +            LL_WARNS("Init") << "Unable to set signal on global setting '" << no_verify_ssl +                << "'" << LL_ENDL; +        } +        else +        { +            mSSLNoVerifySignal = cntrl_ptr->getCommitSignal()->connect(boost::bind(&ssl_verification_changed)); +            LLCore::HttpOptions::setDefaultSSLVerifyPeer(!cntrl_ptr->getValue().asBoolean()); +        } +    } +  	// Tracing levels for library & libcurl (note that 2 & 3 are beyond spammy):  	// 0 - None  	// 1 - Basic start, stop simple transitions @@ -296,6 +314,11 @@ void setting_changed()  	LLAppViewer::instance()->getAppCoreHttp().refreshSettings(false);  } +void ssl_verification_changed() +{ +    LLCore::HttpOptions::setDefaultSSLVerifyPeer(!gSavedSettings.getBOOL("NoVerifySSLCert")); +} +  namespace  {      // The NoOpDeletor is used when wrapping LLAppCoreHttp in a smart pointer below for @@ -355,6 +378,7 @@ void LLAppCoreHttp::cleanup()  	{  		mHttpClasses[i].mSettingsSignal.disconnect();  	} +    mSSLNoVerifySignal.disconnect();  	mPipelinedSignal.disconnect();  	delete mRequest; diff --git a/indra/newview/llappcorehttp.h b/indra/newview/llappcorehttp.h index 95c138d598..751c498ab0 100644 --- a/indra/newview/llappcorehttp.h +++ b/indra/newview/llappcorehttp.h @@ -256,6 +256,7 @@ private:  	HttpClass					mHttpClasses[AP_COUNT];  	bool						mPipelined;				// Global setting  	boost::signals2::connection	mPipelinedSignal;		// Signal for 'HttpPipelining' setting +	boost::signals2::connection	mSSLNoVerifySignal;		// Signal for 'NoVerifySSLCert' setting  	static LLCore::HttpStatus	sslVerify(const std::string &uri, const LLCore::HttpHandler::ptr_t &handler, void *appdata);  }; diff --git a/indra/newview/llappdelegate-objc.mm b/indra/newview/llappdelegate-objc.mm index 3f1b5139c5..aeb3294f53 100644 --- a/indra/newview/llappdelegate-objc.mm +++ b/indra/newview/llappdelegate-objc.mm @@ -66,6 +66,7 @@  	constructViewer();  #if defined(LL_BUGSPLAT) +    infos("bugsplat setup");  	// Engage BugsplatStartupManager *before* calling initViewer() to handle  	// any crashes during initialization.  	// https://www.bugsplat.com/docs/platforms/os-x#initialization @@ -74,6 +75,7 @@  	[BugsplatStartupManager sharedManager].delegate = self;  	[[BugsplatStartupManager sharedManager] start];  #endif +    infos("post-bugsplat setup");  	frameTimer = nil; @@ -301,9 +303,13 @@ struct AttachmentInfo      // We "happen to know" that info[0].basename is "SecondLife.old" -- due to      // the fact that BugsplatMac only notices a crash during the viewer run -    // following the crash. Replace .old with .log to reduce confusion. +    // following the crash.  +    // The Bugsplat service doesn't respect the MIME type above when returning +    // the log data to a browser, so take this opportunity to rename the file +    // from <base>.old to <base>_log.txt      info[0].basename =  -        boost::filesystem::path(info[0].pathname).stem().string() + ".log"; +        boost::filesystem::path(info[0].pathname).stem().string() + "_log.txt"; +    infos("attachmentsForBugsplatStartupManager attaching log " + info[0].basename);      NSMutableArray *attachments = [[NSMutableArray alloc] init]; diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index e8a3305645..9fc2e9ead8 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -3626,7 +3626,7 @@ void LLAppearanceMgr::serverAppearanceUpdateCoro(LLCoreHttpUtil::HttpCoroutineAd      }      llcoro::suspend(); -    if (LLApp::isQuitting()) +    if (LLApp::isExiting())      {          return;      } @@ -3693,7 +3693,7 @@ void LLAppearanceMgr::serverAppearanceUpdateCoro(LLCoreHttpUtil::HttpCoroutineAd          LLSD result = httpAdapter->postAndSuspend(httpRequest, url, postData); -        if (LLApp::isQuitting()) +        if (LLApp::isExiting())          {              return;          } @@ -3733,7 +3733,7 @@ void LLAppearanceMgr::serverAppearanceUpdateCoro(LLCoreHttpUtil::HttpCoroutineAd                  LL_WARNS("Avatar") << "Bake retry #" << retryCount << " in " << timeout << " seconds." << LL_ENDL;                  llcoro::suspendUntilTimeout(timeout);  -                if (LLApp::isQuitting()) +                if (LLApp::isExiting())                  {                      return;                  } diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 053c0a5ab7..891722e1bd 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -59,6 +59,7 @@  #include "llslurl.h"  #include "llstartup.h"  #include "llfocusmgr.h" +#include "llurlfloaterdispatchhandler.h"  #include "llviewerjoystick.h"  #include "llallocator.h"  #include "llcalc.h" @@ -729,14 +730,14 @@ LLAppViewer::LLAppViewer()  	// from the previous viewer run between this constructor call and the  	// init() call, which will overwrite the static_debug_info.log file for  	// THIS run. So setDebugFileNames() early. -#if LL_BUGSPLAT +#   ifdef LL_BUGSPLAT  	// MAINT-8917: don't create a dump directory just for the  	// static_debug_info.log file  	std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, ""); -#else // ! LL_BUGSPLAT +#   else // ! LL_BUGSPLAT  	// write Google Breakpad minidump files to a per-run dump directory to avoid multiple viewer issues.  	std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_DUMP, ""); -#endif // ! LL_BUGSPLAT +#   endif // ! LL_BUGSPLAT  	mDumpPath = logdir;  	setMiniDumpDir(logdir);  	setDebugFileNames(logdir); @@ -761,17 +762,6 @@ public:  	}  }; -namespace { -// With Xcode 6, _exit() is too magical to use with boost::bind(), so provide -// this little helper function. -void fast_exit(int rc) -{ -	_exit(rc); -} - - -} -  bool LLAppViewer::init()  { @@ -823,9 +813,9 @@ bool LLAppViewer::init()  	if (rc >= 0)  	{  		// QAModeTermCode set, terminate with that rc on LL_ERRS. Use -		// fast_exit() rather than exit() because normal cleanup depends too +		// _exit() rather than exit() because normal cleanup depends too  		// much on successful startup! -		LLError::setFatalFunction(boost::bind(fast_exit, rc)); +		LLError::setFatalFunction([rc](const std::string&){ _exit(rc); });  	}      mAlloc.setProfilingEnabled(gSavedSettings.getBOOL("MemProfiling")); @@ -918,6 +908,7 @@ bool LLAppViewer::init()  	// Load translations for tooltips  	LLFloater::initClass(); +	LLUrlFloaterDispatchHandler::registerInDispatcher();  	///////////////////////////////////////////////// @@ -2194,28 +2185,6 @@ bool LLAppViewer::cleanup()  	return true;  } -// A callback for LL_ERRS() to call during the watchdog error. -void watchdog_llerrs_callback(const std::string &error_string) -{ -	gLLErrorActivated = true; - -	gDebugInfo["FatalMessage"] = error_string; -	LLAppViewer::instance()->writeDebugInfo(); - -#ifdef LL_WINDOWS -	RaiseException(0,0,0,0); -#else -	raise(SIGQUIT); -#endif -} - -// A callback for the watchdog to call. -void watchdog_killer_callback() -{ -	LLError::setFatalFunction(watchdog_llerrs_callback); -	LL_ERRS() << "Watchdog killer event" << LL_ENDL; -} -  bool LLAppViewer::initThreads()  {  	static const bool enable_threads = true; @@ -2250,24 +2219,23 @@ bool LLAppViewer::initThreads()  	return true;  } -void errorCallback(const std::string &error_string) +void errorCallback(LLError::ELevel level, const std::string &error_string)  { +    if (level == LLError::LEVEL_ERROR) +    {  #ifndef LL_RELEASE_FOR_DOWNLOAD -	OSMessageBox(error_string, LLTrans::getString("MBFatalError"), OSMB_OK); +        OSMessageBox(error_string, LLTrans::getString("MBFatalError"), OSMB_OK);  #endif -	//Set the ErrorActivated global so we know to create a marker file -	gLLErrorActivated = true; +        //Set the ErrorActivated global so we know to create a marker file +        gLLErrorActivated = true; -	gDebugInfo["FatalMessage"] = error_string; -	// We're not already crashing -- we simply *intend* to crash. Since we -	// haven't actually trashed anything yet, we can afford to write the whole -	// static info file. -	LLAppViewer::instance()->writeDebugInfo(); - -#ifndef SHADER_CRASH_NONFATAL -	LLError::crashAndLoop(error_string); -#endif +        gDebugInfo["FatalMessage"] = error_string; +        // We're not already crashing -- we simply *intend* to crash. Since we +        // haven't actually trashed anything yet, we can afford to write the whole +        // static info file. +        LLAppViewer::instance()->writeDebugInfo(); +    }  }  void LLAppViewer::initLoggingAndGetLastDuration() @@ -2278,7 +2246,7 @@ void LLAppViewer::initLoggingAndGetLastDuration()  	LLError::initForApplication( gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "")                                  ,gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "")                                  ); -	LLError::setFatalFunction(errorCallback); +	LLError::addGenericRecorder(&errorCallback);  	//LLError::setTimeFunction(getRuntime);  	// Remove the last ".old" log file. @@ -3037,11 +3005,16 @@ bool LLAppViewer::initWindow()  		use_watchdog = bool(watchdog_enabled_setting);  	} +	LL_INFOS("AppInit") << "watchdog" +						<< (use_watchdog ? " " : " NOT ") +						<< "enabled" +						<< " (setting = " << watchdog_enabled_setting << ")" +						<< LL_ENDL; +  	if (use_watchdog)  	{ -		LLWatchdog::getInstance()->init(watchdog_killer_callback); +		LLWatchdog::getInstance()->init();  	} -	LL_INFOS("AppInit") << "watchdog setting is done." << LL_ENDL;  	LLNotificationsUI::LLNotificationManager::getInstance(); @@ -3474,8 +3447,8 @@ void LLAppViewer::writeSystemInfo()  	gDebugInfo["CPUInfo"]["CPUSSE"] = gSysCPU.hasSSE();  	gDebugInfo["CPUInfo"]["CPUSSE2"] = gSysCPU.hasSSE2(); -	gDebugInfo["RAMInfo"]["Physical"] = (LLSD::Integer)(gSysMemory.getPhysicalMemoryKB().value()); -	gDebugInfo["RAMInfo"]["Allocated"] = (LLSD::Integer)(gMemoryAllocated.valueInUnits<LLUnits::Kilobytes>()); +	gDebugInfo["RAMInfo"]["Physical"] = LLSD::Integer(gSysMemory.getPhysicalMemoryKB().value()); +	gDebugInfo["RAMInfo"]["Allocated"] = LLSD::Integer(gMemoryAllocated.valueInUnits<LLUnits::Kilobytes>());  	gDebugInfo["OSInfo"] = LLOSInfo::instance().getOSStringSimple();  	// The user is not logged on yet, but record the current grid choice login url @@ -3488,12 +3461,18 @@ void LLAppViewer::writeSystemInfo()  	gDebugInfo["MainloopThreadID"] = (S32)thread_id;  #endif +#ifndef LL_BUGSPLAT  	// "CrashNotHandled" is set here, while things are running well,  	// in case of a freeze. If there is a freeze, the crash logger will be launched  	// and can read this value from the debug_info.log.  	// If the crash is handled by LLAppViewer::handleViewerCrash, ie not a freeze,  	// then the value of "CrashNotHandled" will be set to true. -	gDebugInfo["CrashNotHandled"] = (LLSD::Boolean)true; +	gDebugInfo["CrashNotHandled"] = LLSD::Boolean(true); +#else // LL_BUGSPLAT +	// "CrashNotHandled" is obsolete; it used (not very successsfully) +    // to try to distinguish crashes from freezes - the intent here to to avoid calling it a freeze +	gDebugInfo["CrashNotHandled"] = LLSD::Boolean(false); +#endif // ! LL_BUGSPLAT  	// Insert crash host url (url to post crash log to) if configured. This insures  	// that the crash report will go to the proper location in the case of a @@ -3524,7 +3503,7 @@ void LLAppViewer::writeSystemInfo()      gDebugInfo["SettingsFilename"] = gSavedSettings.getString("ClientSettingsFile");  	gDebugInfo["ViewerExePath"] = gDirUtilp->getExecutablePathAndName();  	gDebugInfo["CurrentPath"] = gDirUtilp->getCurPath(); -	gDebugInfo["FirstLogin"] = (LLSD::Boolean) gAgent.isFirstLogin(); +	gDebugInfo["FirstLogin"] = LLSD::Boolean(gAgent.isFirstLogin());  	gDebugInfo["FirstRunThisInstall"] = gSavedSettings.getBOOL("FirstRunThisInstall");      gDebugInfo["StartupState"] = LLStartUp::getStartupStateString(); @@ -3654,7 +3633,7 @@ void LLAppViewer::handleViewerCrash()  	// The crash is being handled here so set this value to false.  	// Otherwise the crash logger will think this crash was a freeze. -	gDebugInfo["Dynamic"]["CrashNotHandled"] = (LLSD::Boolean)false; +	gDebugInfo["Dynamic"]["CrashNotHandled"] = LLSD::Boolean(false);  	//Write out the crash status file  	//Use marker file style setup, as that's the simplest, especially since @@ -3727,6 +3706,8 @@ void LLAppViewer::handleViewerCrash()  	if (LLWorld::instanceExists()) LLWorld::getInstance()->getInfo(gDebugInfo["Dynamic"]); +	gDebugInfo["FatalMessage"] = LLError::getFatalMessage(); +  	// Close the debug file  	pApp->writeDebugInfo(false);  //false answers the isStatic question with the least overhead.  } @@ -3825,9 +3806,8 @@ void LLAppViewer::processMarkerFiles()  		else if (marker_is_same_version)  		{  			// the file existed, is ours, and matched our version, so we can report on what it says -			LL_INFOS("MarkerFile") << "Exec marker '"<< mMarkerFileName << "' found; last exec FROZE" << LL_ENDL; -			gLastExecEvent = LAST_EXEC_FROZE; - +			LL_INFOS("MarkerFile") << "Exec marker '"<< mMarkerFileName << "' found; last exec crashed" << LL_ENDL; +			gLastExecEvent = LAST_EXEC_OTHER_CRASH;  		}  		else  		{ @@ -5371,10 +5351,9 @@ void LLAppViewer::sendLogoutRequest()  	}  } -void LLAppViewer::updateNameLookupUrl() +void LLAppViewer::updateNameLookupUrl(const LLViewerRegion * regionp)  { -    LLViewerRegion* region = gAgent.getRegion(); -    if (!region || !region->capabilitiesReceived()) +    if (!regionp || !regionp->capabilitiesReceived())      {          return;      } @@ -5383,7 +5362,7 @@ void LLAppViewer::updateNameLookupUrl()      bool had_capability = LLAvatarNameCache::getInstance()->hasNameLookupURL();      std::string name_lookup_url;      name_lookup_url.reserve(128); // avoid a memory allocation below -    name_lookup_url = region->getCapability("GetDisplayNames"); +    name_lookup_url = regionp->getCapability("GetDisplayNames");      bool have_capability = !name_lookup_url.empty();      if (have_capability)      { @@ -5694,6 +5673,33 @@ void LLAppViewer::forceErrorDriverCrash()  	glDeleteTextures(1, NULL);  } +void LLAppViewer::forceErrorCoroutineCrash() +{ +    LL_WARNS() << "Forcing a crash in LLCoros" << LL_ENDL; +    LLCoros::instance().launch("LLAppViewer::crashyCoro", [] {throw LLException("A deliberate crash from LLCoros"); }); +} + +void LLAppViewer::forceErrorThreadCrash() +{ +    class LLCrashTestThread : public LLThread +    { +    public: + +        LLCrashTestThread() : LLThread("Crash logging test thread") +        { +        } + +        void run() +        { +            LL_ERRS() << "This is a deliberate llerror in thread" << LL_ENDL; +        } +    }; + +    LL_WARNS() << "This is a deliberate crash in a thread" << LL_ENDL; +    LLCrashTestThread *thread = new LLCrashTestThread(); +    thread->start(); +} +  void LLAppViewer::initMainloopTimeout(const std::string& state, F32 secs)  {  	if(!mMainloopTimeout) @@ -5737,11 +5743,6 @@ void LLAppViewer::pauseMainloopTimeout()  void LLAppViewer::pingMainloopTimeout(const std::string& state, F32 secs)  { -//	if(!restoreErrorTrap()) -//	{ -//		LL_WARNS() << "!!!!!!!!!!!!! Its an error trap!!!!" << state << LL_ENDL; -//	} -  	if(mMainloopTimeout)  	{  		if(secs < 0.0f) diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index 5ceb540784..0afb70958c 100644 --- a/indra/newview/llappviewer.h +++ b/indra/newview/llappviewer.h @@ -57,6 +57,7 @@ class LLImageDecodeThread;  class LLTextureFetch;  class LLWatchdogTimeout;  class LLViewerJoystick; +class LLViewerRegion;  extern LLTrace::BlockTimerStatHandle FTM_FRAME; @@ -150,6 +151,8 @@ public:      virtual void forceErrorInfiniteLoop();      virtual void forceErrorSoftwareException();      virtual void forceErrorDriverCrash(); +    virtual void forceErrorCoroutineCrash(); +    virtual void forceErrorThreadCrash();  	// The list is found in app_settings/settings_files.xml  	// but since they are used explicitly in code, @@ -209,7 +212,7 @@ public:  	// llcorehttp init/shutdown/config information.  	LLAppCoreHttp & getAppCoreHttp()			{ return mAppCoreHttp; } -    void updateNameLookupUrl(); +    void updateNameLookupUrl(const LLViewerRegion* regionp);  protected:  	virtual bool initWindow(); // Initialize the viewer's window. diff --git a/indra/newview/llappviewermacosx.cpp b/indra/newview/llappviewermacosx.cpp index 662164af2d..42946e4415 100644 --- a/indra/newview/llappviewermacosx.cpp +++ b/indra/newview/llappviewermacosx.cpp @@ -68,39 +68,21 @@ namespace  	int gArgC;  	char** gArgV;  	LLAppViewerMacOSX* gViewerAppPtr = NULL; - -    void (*gOldTerminateHandler)() = NULL;      std::string gHandleSLURL;  } -static void exceptionTerminateHandler() -{ -	// reinstall default terminate() handler in case we re-terminate. -	if (gOldTerminateHandler) std::set_terminate(gOldTerminateHandler); -	// treat this like a regular viewer crash, with nice stacktrace etc. -    long *null_ptr; -    null_ptr = 0; -    *null_ptr = 0xDEADBEEF; //Force an exception that will trigger breakpad. -	//LLAppViewer::handleViewerCrash(); -	// we've probably been killed-off before now, but... -	gOldTerminateHandler(); // call old terminate() handler -} -  void constructViewer()  {  	// Set the working dir to <bundle>/Contents/Resources  	if (chdir(gDirUtilp->getAppRODataDir().c_str()) == -1)  	{ -		LL_WARNS() << "Could not change directory to " +		LL_WARNS("InitOSX") << "Could not change directory to "  				<< gDirUtilp->getAppRODataDir() << ": " << strerror(errno)  				<< LL_ENDL;  	}  	gViewerAppPtr = new LLAppViewerMacOSX(); -    // install unexpected exception handler -	gOldTerminateHandler = std::set_terminate(exceptionTerminateHandler); -  	gViewerAppPtr->setErrorHandler(LLAppViewer::handleViewerCrash);  } @@ -109,7 +91,7 @@ bool initViewer()  	bool ok = gViewerAppPtr->init();  	if(!ok)  	{ -		LL_WARNS() << "Application init failed." << LL_ENDL; +		LL_WARNS("InitOSX") << "Application init failed." << LL_ENDL;  	}  	else if (!gHandleSLURL.empty())  	{ @@ -172,7 +154,7 @@ class CrashMetadataSingleton: public CrashMetadata, public LLSingleton<CrashMeta      std::string get_metadata(const LLSD& info, const LLSD::String& key) const      {          std::string data(info[key].asString()); -        LL_INFOS() << "  " << key << "='" << data << "'" << LL_ENDL; +        LL_INFOS("Bugsplat") << "  " << key << "='" << data << "'" << LL_ENDL;          return data;      }  }; @@ -188,22 +170,22 @@ CrashMetadataSingleton::CrashMetadataSingleton()      LLSD info;      if (! static_file.is_open())      { -        LL_INFOS() << "Can't open '" << staticDebugPathname +        LL_WARNS("Bugsplat") << "Can't open '" << staticDebugPathname                     << "'; no metadata about previous run" << LL_ENDL;      }      else if (! LLSDSerialize::deserialize(info, static_file, LLSDSerialize::SIZE_UNLIMITED))      { -        LL_INFOS() << "Can't parse '" << staticDebugPathname +        LL_WARNS("Bugsplat") << "Can't parse '" << staticDebugPathname                     << "'; no metadata about previous run" << LL_ENDL;      }      else      { -        LL_INFOS() << "Metadata from '" << staticDebugPathname << "':" << LL_ENDL; -        logFilePathname         = get_metadata(info, "SLLog"); -        userSettingsPathname    = get_metadata(info, "SettingsFilename"); +        LL_INFOS("Bugsplat") << "Previous run metadata from '" << staticDebugPathname << "':" << LL_ENDL; +        logFilePathname      = get_metadata(info, "SLLog"); +        userSettingsPathname = get_metadata(info, "SettingsFilename");          accountSettingsPathname = get_metadata(info, "PerAccountSettingsFilename"); -        OSInfo                  = get_metadata(info, "OSInfo"); -        agentFullname           = get_metadata(info, "LoginName"); +        OSInfo               = get_metadata(info, "OSInfo"); +        agentFullname        = get_metadata(info, "LoginName");          // Translate underscores back to spaces          LLStringUtil::replaceChar(agentFullname, '_', ' ');          regionName           = get_metadata(info, "CurrentRegion"); @@ -219,7 +201,7 @@ CrashMetadata& CrashMetadata_instance()  void infos(const std::string& message)  { -    LL_INFOS() << message << LL_ENDL; +    LL_INFOS("InitOSX", "Bugsplat") << message << LL_ENDL;  }  int main( int argc, char **argv )  @@ -242,14 +224,11 @@ bool LLAppViewerMacOSX::init()  {  	bool success = LLAppViewer::init(); -#if LL_SEND_CRASH_REPORTS      if (success)      {          LLAppViewer* pApp = LLAppViewer::instance();          pApp->initCrashReporting();      } -#endif -          return success;  } @@ -334,11 +313,12 @@ bool LLAppViewerMacOSX::restoreErrorTrap()  	unsigned int reset_count = 0; -#define SET_SIG(S) 	sigaction(SIGABRT, &act, &old_act); \ -					if(act.sa_sigaction != old_act.sa_sigaction) \ -						++reset_count; +#define SET_SIG(SIGNAL) sigaction(SIGNAL, &act, &old_act); \ +                        if(act.sa_sigaction != old_act.sa_sigaction) ++reset_count;  	// Synchronous signals -	SET_SIG(SIGABRT) +#   ifndef LL_BUGSPLAT +	SET_SIG(SIGABRT) // let bugsplat catch this +#   endif          	SET_SIG(SIGALRM)  	SET_SIG(SIGBUS)  	SET_SIG(SIGFPE) @@ -369,6 +349,10 @@ bool LLAppViewerMacOSX::restoreErrorTrap()  void LLAppViewerMacOSX::initCrashReporting(bool reportFreeze)  { +#if defined LL_BUGSPLAT +    LL_DEBUGS("InitOSX", "Bugsplat") << "using BugSplat crash logger" << LL_ENDL; +#elif LL_SEND_CRASH_REPORTS +    LL_DEBUGS("InitOSX") << "Initializing legacy crash logger" << LL_ENDL;  	std::string command_str = "mac-crash-logger.app";      std::stringstream pid_str; @@ -380,6 +364,9 @@ void LLAppViewerMacOSX::initCrashReporting(bool reportFreeze)      LL_WARNS() << "about to launch mac-crash-logger" << pid_str.str()                 << " " << logdir << " " << appname << LL_ENDL;      launchApplication(&command_str, &args); +#else +    LL_DEBUGS("InitOSX") << "No crash logger enabled" << LL_ENDL;     +#endif // ! LL_BUGSPLAT  }  std::string LLAppViewerMacOSX::generateSerialNumber() @@ -391,7 +378,8 @@ std::string LLAppViewerMacOSX::generateSerialNumber()  	CFStringRef serialNumber = NULL;  	io_service_t    platformExpert = IOServiceGetMatchingService(kIOMasterPortDefault,  																 IOServiceMatching("IOPlatformExpertDevice")); -	if (platformExpert) { +	if (platformExpert) +    {  		serialNumber = (CFStringRef) IORegistryEntryCreateCFProperty(platformExpert,  																	 CFSTR(kIOPlatformSerialNumberKey),  																	 kCFAllocatorDefault, 0);		 diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp index 9b1c0d1f8b..9daea515e5 100644 --- a/indra/newview/llappviewerwin32.cpp +++ b/indra/newview/llappviewerwin32.cpp @@ -177,7 +177,7 @@ static void exceptionTerminateHandler()      long *null_ptr;      null_ptr = 0;      *null_ptr = 0xDEADBEEF; //Force an exception that will trigger breakpad. -	//LLAppViewer::handleViewerCrash(); +  	// we've probably been killed-off before now, but...  	gOldTerminateHandler(); // call old terminate() handler  } @@ -365,10 +365,6 @@ int APIENTRY WINMAIN(HINSTANCE hInstance,  	viewer_app_ptr->setErrorHandler(LLAppViewer::handleViewerCrash); -#if LL_SEND_CRASH_REPORTS  -	// ::SetUnhandledExceptionFilter(catchallCrashHandler);  -#endif -  	// Set a debug info flag to indicate if multiple instances are running.  	bool found_other_instance = !create_app_mutex();  	gDebugInfo["FoundOtherInstanceAtStartup"] = LLSD::Boolean(found_other_instance); @@ -609,6 +605,13 @@ bool LLAppViewerWin32::init()  #else // LL_BUGSPLAT  #pragma message("Building with BugSplat") +    if (!isSecondInstance()) +    { +        // Cleanup previous session +        std::string log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "bugsplat.log"); +        LLFile::remove(log_file, ENOENT); +    } +  	std::string build_data_fname(  		gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "build_data.json"));  	// Use llifstream instead of std::ifstream because LL_PATH_EXECUTABLE @@ -616,7 +619,7 @@ bool LLAppViewerWin32::init()  	llifstream inf(build_data_fname.c_str());  	if (! inf.is_open())  	{ -		LL_WARNS() << "Can't initialize BugSplat, can't read '" << build_data_fname +		LL_WARNS("BUGSPLAT") << "Can't initialize BugSplat, can't read '" << build_data_fname  				   << "'" << LL_ENDL;  	}  	else @@ -626,7 +629,7 @@ bool LLAppViewerWin32::init()  		if (! reader.parse(inf, build_data, false)) // don't collect comments  		{  			// gah, the typo is baked into Json::Reader API -			LL_WARNS() << "Can't initialize BugSplat, can't parse '" << build_data_fname +			LL_WARNS("BUGSPLAT") << "Can't initialize BugSplat, can't parse '" << build_data_fname  					   << "': " << reader.getFormatedErrorMessages() << LL_ENDL;  		}  		else @@ -634,7 +637,7 @@ bool LLAppViewerWin32::init()  			Json::Value BugSplat_DB = build_data["BugSplat DB"];  			if (! BugSplat_DB)  			{ -				LL_WARNS() << "Can't initialize BugSplat, no 'BugSplat DB' entry in '" +				LL_WARNS("BUGSPLAT") << "Can't initialize BugSplat, no 'BugSplat DB' entry in '"  						   << build_data_fname << "'" << LL_ENDL;  			}  			else @@ -645,18 +648,35 @@ bool LLAppViewerWin32::init()  													   LL_VIEWER_VERSION_PATCH << '.' <<  													   LL_VIEWER_VERSION_BUILD)); +                DWORD dwFlags = MDSF_NONINTERACTIVE | // automatically submit report without prompting +                                MDSF_PREVENTHIJACKING; // disallow swiping Exception filter + +                bool needs_log_file = !isSecondInstance() && debugLoggingEnabled("BUGSPLAT"); +                if (needs_log_file) +                { +                    // Startup only! +                    LL_INFOS("BUGSPLAT") << "Engaged BugSplat logging to bugsplat.log" << LL_ENDL; +                    dwFlags |= MDSF_LOGFILE | MDSF_LOG_VERBOSE; +                } +  				// have to convert normal wide strings to strings of __wchar_t  				sBugSplatSender = new MiniDmpSender(  					WCSTR(BugSplat_DB.asString()),  					WCSTR(LL_TO_WSTRING(LL_VIEWER_CHANNEL)),  					WCSTR(version_string),  					nullptr,              // szAppIdentifier -- set later -					MDSF_NONINTERACTIVE | // automatically submit report without prompting -					MDSF_PREVENTHIJACKING); // disallow swiping Exception filter +					dwFlags);  				sBugSplatSender->setCallback(bugsplatSendLog); +                if (needs_log_file) +                { +                    // Log file will be created in %TEMP%, but it will be moved into logs folder in case of crash +                    std::string log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "bugsplat.log"); +                    sBugSplatSender->setLogFilePath(WCSTR(log_file)); +                } +  				// engage stringize() overload that converts from wstring -				LL_INFOS() << "Engaged BugSplat(" << LL_TO_STRING(LL_VIEWER_CHANNEL) +				LL_INFOS("BUGSPLAT") << "Engaged BugSplat(" << LL_TO_STRING(LL_VIEWER_CHANNEL)  						   << ' ' << stringize(version_string) << ')' << LL_ENDL;  			} // got BugSplat_DB  		} // parsed build_data.json @@ -685,6 +705,16 @@ bool LLAppViewerWin32::cleanup()  	return result;  } +void LLAppViewerWin32::reportCrashToBugsplat(void* pExcepInfo) +{ +#if defined(LL_BUGSPLAT) +    if (sBugSplatSender) +    { +        sBugSplatSender->createReport((EXCEPTION_POINTERS*)pExcepInfo); +    } +#endif // LL_BUGSPLAT +} +  void LLAppViewerWin32::initLoggingAndGetLastDuration()  {  	LLAppViewer::initLoggingAndGetLastDuration(); @@ -813,8 +843,7 @@ bool LLAppViewerWin32::beingDebugged()  bool LLAppViewerWin32::restoreErrorTrap()  {	 -	return true; -	//return LLWinDebug::checkExceptionHandler(); +	return true; // we don't check for handler collisions on windows, so just say they're ok  }  void LLAppViewerWin32::initCrashReporting(bool reportFreeze) diff --git a/indra/newview/llappviewerwin32.h b/indra/newview/llappviewerwin32.h index c5fae6a3a3..83ae875a15 100644 --- a/indra/newview/llappviewerwin32.h +++ b/indra/newview/llappviewerwin32.h @@ -40,20 +40,22 @@ public:  	//  	// Main application logic  	// -	virtual bool init(); // Override to do application initialization -	virtual bool cleanup(); +	bool init() override; // Override to do application initialization +    bool cleanup() override; + +    void reportCrashToBugsplat(void* pExcepInfo) override;  protected: -	virtual void initLoggingAndGetLastDuration(); // Override to clean stack_trace info. -	virtual void initConsole(); // Initialize OS level debugging console. -	virtual bool initHardwareTest(); // Win32 uses DX9 to test hardware. -	virtual bool initParseCommandLine(LLCommandLineParser& clp); +	void initLoggingAndGetLastDuration() override; // Override to clean stack_trace info. +	void initConsole() override; // Initialize OS level debugging console. +	bool initHardwareTest() override; // Win32 uses DX9 to test hardware. +	bool initParseCommandLine(LLCommandLineParser& clp) override; -	virtual bool beingDebugged(); -	virtual bool restoreErrorTrap(); -	virtual void initCrashReporting(bool reportFreeze);  +	bool beingDebugged() override; +	bool restoreErrorTrap() override; +	void initCrashReporting(bool reportFreeze) override; -	virtual bool sendURLToOtherInstance(const std::string& url); +	bool sendURLToOtherInstance(const std::string& url) override;  	std::string generateSerialNumber(); diff --git a/indra/newview/llavatarpropertiesprocessor.cpp b/indra/newview/llavatarpropertiesprocessor.cpp index 44ca3c1b5f..a190f6d5d8 100644 --- a/indra/newview/llavatarpropertiesprocessor.cpp +++ b/indra/newview/llavatarpropertiesprocessor.cpp @@ -253,6 +253,19 @@ std::string LLAvatarPropertiesProcessor::paymentInfo(const LLAvatarData* avatar_  	return LLTrans::getString(payment_text);  } +//static +bool LLAvatarPropertiesProcessor::hasPaymentInfoOnFile(const LLAvatarData* avatar_data) +{ +	// Special accounts like M Linden don't have payment info revealed. +	if (!avatar_data->caption_text.empty()) return true; + +	// Linden employees don't have payment info revealed +	const S32 LINDEN_EMPLOYEE_INDEX = 3; +	if (avatar_data->caption_index == LINDEN_EMPLOYEE_INDEX) return true; + +	return ((avatar_data->flags & AVATAR_TRANSACTED) || (avatar_data->flags & AVATAR_IDENTIFIED)); +} +  void LLAvatarPropertiesProcessor::processAvatarPropertiesReply(LLMessageSystem* msg, void**)  {  	LLAvatarData avatar_data; diff --git a/indra/newview/llavatarpropertiesprocessor.h b/indra/newview/llavatarpropertiesprocessor.h index 1c981d5b2e..ad7327728c 100644 --- a/indra/newview/llavatarpropertiesprocessor.h +++ b/indra/newview/llavatarpropertiesprocessor.h @@ -246,6 +246,8 @@ public:  	// Used for profiles, inspectors.  	static std::string paymentInfo(const LLAvatarData* avatar_data); +	static bool hasPaymentInfoOnFile(const LLAvatarData* avatar_data); +  	static void processAvatarPropertiesReply(LLMessageSystem* msg, void**);  	static void processAvatarInterestsReply(LLMessageSystem* msg, void**); diff --git a/indra/newview/llchatbar.cpp b/indra/newview/llchatbar.cpp index 3ab5c669c4..e400609a74 100644 --- a/indra/newview/llchatbar.cpp +++ b/indra/newview/llchatbar.cpp @@ -58,6 +58,7 @@  #include "llmultigesture.h"  #include "llui.h"  #include "lluictrlfactory.h" +#include "lluiusage.h"  //  // Globals @@ -566,6 +567,8 @@ void LLChatBar::sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL  	// as soon as we say something, we no longer care about teaching the user  	// how to chat  	gWarningSettings.setBOOL("FirstOtherChatBeforeUser", FALSE); + +	LLUIUsage::instance().logCommand("Chat.Send"); // Pseudo-command  	// Look for "/20 foo" channel chats.  	S32 channel = 0; diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp index 2ba2c6d8b5..c110e0d815 100644 --- a/indra/newview/llchathistory.cpp +++ b/indra/newview/llchathistory.cpp @@ -122,6 +122,7 @@ public:  		mUserNameFont(NULL),  		mUserNameTextBox(NULL),  		mTimeBoxTextBox(NULL), +		mNeedsTimeBox(true),  		mAvatarNameCacheConnection()  	{} @@ -643,8 +644,19 @@ public:  		user_name->setReadOnlyColor(style_params.readonly_color());  		user_name->setColor(style_params.color()); -		if (chat.mFromName.empty() -			|| mSourceType == CHAT_SOURCE_SYSTEM) +        if (mSourceType == CHAT_SOURCE_TELEPORT +            && chat.mChatStyle == CHAT_STYLE_TELEPORT_SEP) +        { +            mFrom = chat.mFromName; +            mNeedsTimeBox = false; +            user_name->setValue(mFrom); +            updateMinUserNameWidth(); +            LLColor4 sep_color = LLUIColorTable::instance().getColor("ChatTeleportSeparatorColor"); +            setTransparentColor(sep_color); +            mTimeBoxTextBox->setVisible(FALSE); +        } +        else if (chat.mFromName.empty() +                 || mSourceType == CHAT_SOURCE_SYSTEM)  		{  			mFrom = LLTrans::getString("SECOND_LIFE");  			if(!chat.mFromName.empty() && (mFrom != chat.mFromName)) @@ -728,6 +740,9 @@ public:  			case CHAT_SOURCE_SYSTEM:  				icon->setValue(LLSD("SL_Logo"));  				break; +			case CHAT_SOURCE_TELEPORT: +				icon->setValue(LLSD("Command_Destinations_Icon")); +				break;  			case CHAT_SOURCE_UNKNOWN:   				icon->setValue(LLSD("Unknown_Icon"));  		} @@ -766,7 +781,7 @@ public:  		S32 user_name_width = user_name_rect.getWidth();  		S32 time_box_width = time_box->getRect().getWidth(); -		if (!time_box->getVisible() && user_name_width > mMinUserNameWidth) +		if (mNeedsTimeBox && !time_box->getVisible() && user_name_width > mMinUserNameWidth)  		{  			user_name_rect.mRight -= time_box_width;  			user_name->reshape(user_name_rect.getWidth(), user_name_rect.getHeight()); @@ -968,6 +983,8 @@ protected:  	LLTextBox*			mUserNameTextBox;  	LLTextBox*			mTimeBoxTextBox;  +    bool				mNeedsTimeBox; +  private:  	boost::signals2::connection mAvatarNameCacheConnection;  }; @@ -1202,6 +1219,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL  	}  	bool message_from_log = chat.mChatStyle == CHAT_STYLE_HISTORY; +	bool teleport_separator = chat.mSourceType == CHAT_SOURCE_TELEPORT;  	// We graying out chat history by graying out messages that contains full date in a time string  	if (message_from_log)  	{ @@ -1222,14 +1240,14 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL  		LLStyle::Params timestamp_style(body_message_params);  		// out of the timestamp -		if (args["show_time"].asBoolean()) -		{ -		if (!message_from_log) +		if (args["show_time"].asBoolean() && !teleport_separator)  		{ -			LLColor4 timestamp_color = LLUIColorTable::instance().getColor("ChatTimestampColor"); -			timestamp_style.color(timestamp_color); -			timestamp_style.readonly_color(timestamp_color); -		} +			if (!message_from_log) +			{ +				LLColor4 timestamp_color = LLUIColorTable::instance().getColor("ChatTimestampColor"); +				timestamp_style.color(timestamp_color); +				timestamp_style.readonly_color(timestamp_color); +			}  			mEditor->appendText("[" + chat.mTimeStr + "] ", prependNewLineState, timestamp_style);  			prependNewLineState = false;  		} @@ -1272,6 +1290,13 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL  					prependNewLineState, link_params);  				prependNewLineState = false;  			} +            else if (teleport_separator) +            { +                std::string tp_text = LLTrans::getString("teleport_preamble_compact_chat"); +                mEditor->appendText(tp_text + " <nolink>" + chat.mFromName + "</nolink>", +                    prependNewLineState, body_message_params); +                                prependNewLineState = false; +            }  			else  			{  				mEditor->appendText("<nolink>" + chat.mFromName + "</nolink>" + delimiter, @@ -1290,8 +1315,8 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL  		p.right_pad = mRightWidgetPad;  		LLDate new_message_time = LLDate::now(); - -		if (mLastFromName == chat.mFromName  +		if (!teleport_separator +			&& mLastFromName == chat.mFromName  			&& mLastFromID == chat.mFromID  			&& mLastMessageTime.notNull()   			&& (new_message_time.secondsSinceEpoch() - mLastMessageTime.secondsSinceEpoch()) < 60.0 @@ -1314,7 +1339,14 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL  				p.top_pad = 0;  			else  				p.top_pad = mTopHeaderPad; -            p.bottom_pad = mBottomHeaderPad; +            if (teleport_separator) +            { +                p.bottom_pad = mBottomSeparatorPad; +            } +            else +            { +                p.bottom_pad = mBottomHeaderPad; +            }              if (!view)              {                  LL_WARNS() << "Failed to create header from " << mMessageHeaderFilename << ": can't append to history" << LL_ENDL; @@ -1392,9 +1424,8 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL  			}  		}  	} -  	// usual messages showing -	else +	else if(!teleport_separator)  	{  		std::string message = irc_me ? chat.mText.substr(3) : chat.mText; @@ -1427,7 +1458,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL  		if (square_brackets)  		{  			message += "]"; -	} +		}  		mEditor->appendText(message, prependNewLineState, body_message_params);  		prependNewLineState = false; diff --git a/indra/newview/llcompilequeue.cpp b/indra/newview/llcompilequeue.cpp index 3aaaaf52f5..bf10a9f2b4 100644 --- a/indra/newview/llcompilequeue.cpp +++ b/indra/newview/llcompilequeue.cpp @@ -347,7 +347,7 @@ void LLFloaterCompileQueue::processExperienceIdResults(LLSD result, LLUUID paren  bool LLFloaterCompileQueue::processScript(LLHandle<LLFloaterCompileQueue> hfloater,      const LLPointer<LLViewerObject> &object, LLInventoryObject* inventory, LLEventPump &pump)  { -    if (LLApp::isQuitting()) +    if (LLApp::isExiting())      {          // Reply from coroutine came on shutdown          // We are quiting, don't start any more coroutines! diff --git a/indra/newview/llcurrencyuimanager.cpp b/indra/newview/llcurrencyuimanager.cpp index d4fc1fe64d..232e461fd0 100644 --- a/indra/newview/llcurrencyuimanager.cpp +++ b/indra/newview/llcurrencyuimanager.cpp @@ -454,7 +454,7 @@ void LLCurrencyUIManager::Impl::updateUI()  		if (!mUserEnteredCurrencyBuy)  		{ -			if (!mZeroMessage.empty() && mUserCurrencyBuy == 0) +			if (mUserCurrencyBuy == 0)  			{  				lindenAmount->setText(LLStringUtil::null);  			} @@ -467,8 +467,9 @@ void LLCurrencyUIManager::Impl::updateUI()  		}  	} -	mPanel.getChild<LLUICtrl>("currency_est")->setTextArg("[LOCALAMOUNT]", getLocalEstimate()); -	mPanel.getChildView("currency_est")->setVisible( hasEstimate() && mUserCurrencyBuy > 0); +	std::string estimated = (mUserCurrencyBuy == 0) ? mPanel.getString("estimated_zero") : getLocalEstimate(); +	mPanel.getChild<LLUICtrl>("currency_est")->setTextArg("[LOCALAMOUNT]", estimated); +	mPanel.getChildView("currency_est")->setVisible( hasEstimate() || mUserCurrencyBuy == 0);  	mPanel.getChildView("currency_links")->setVisible( mSupportsInternationalBilling);  	mPanel.getChildView("exchange_rate_note")->setVisible( mSupportsInternationalBilling); diff --git a/indra/newview/lldelayedgestureerror.cpp b/indra/newview/lldelayedgestureerror.cpp index ef1b644ad4..934a38bb8e 100644 --- a/indra/newview/lldelayedgestureerror.cpp +++ b/indra/newview/lldelayedgestureerror.cpp @@ -113,7 +113,7 @@ bool LLDelayedGestureError::doDialog(const LLErrorEntry &ent, bool uuid_ok)  		}  	} -	if(!LLApp::isQuitting()) +	if(!LLApp::isExiting())  	{  		LLNotificationsUtil::add(ent.mNotifyName, args);  	} diff --git a/indra/newview/llenvironment.cpp b/indra/newview/llenvironment.cpp index 74c1b99e4d..8881d11802 100644 --- a/indra/newview/llenvironment.cpp +++ b/indra/newview/llenvironment.cpp @@ -327,7 +327,7 @@ namespace                  std::istringstream llsdData(llsdRaw);                  if (!LLSDSerialize::deserialize(message, llsdData, llsdRaw.length()))                  { -                    LL_WARNS() << "LLExperienceLogDispatchHandler: Attempted to read parameter data into LLSD but failed:" << llsdRaw << LL_ENDL; +                    LL_WARNS() << "LLEnvironmentPushDispatchHandler: Attempted to read parameter data into LLSD but failed:" << llsdRaw << LL_ENDL;                  }              } @@ -785,11 +785,11 @@ namespace  }  //========================================================================= -const F32Seconds LLEnvironment::TRANSITION_INSTANT(0.0f); -const F32Seconds LLEnvironment::TRANSITION_FAST(1.0f); -const F32Seconds LLEnvironment::TRANSITION_DEFAULT(5.0f); -const F32Seconds LLEnvironment::TRANSITION_SLOW(10.0f); -const F32Seconds LLEnvironment::TRANSITION_ALTITUDE(5.0f); +const F64Seconds LLEnvironment::TRANSITION_INSTANT(0.0f); +const F64Seconds LLEnvironment::TRANSITION_FAST(1.0f); +const F64Seconds LLEnvironment::TRANSITION_DEFAULT(5.0f); +const F64Seconds LLEnvironment::TRANSITION_SLOW(10.0f); +const F64Seconds LLEnvironment::TRANSITION_ALTITUDE(5.0f);  const LLUUID LLEnvironment::KNOWN_SKY_SUNRISE("01e41537-ff51-2f1f-8ef7-17e4df760bfb");  const LLUUID LLEnvironment::KNOWN_SKY_MIDDAY("6c83e853-e7f8-cad7-8ee6-5f31c453721c"); @@ -1029,7 +1029,7 @@ void LLEnvironment::onRegionChange()      }      if (!cur_region->capabilitiesReceived())      { -        cur_region->setCapabilitiesReceivedCallback([](const LLUUID ®ion_id) {  LLEnvironment::instance().requestRegion(); }); +        cur_region->setCapabilitiesReceivedCallback([](const LLUUID ®ion_id, LLViewerRegion* regionp) {  LLEnvironment::instance().requestRegion(); });          return;      }      requestRegion(); @@ -1154,9 +1154,38 @@ void LLEnvironment::setEnvironment(LLEnvironment::EnvSelection_t env, LLEnvironm      }      else if (!environment->getSky())      { -        LL_DEBUGS("ENVIRONMENT") << "Blank sky for " << env_selection_to_string(env) << ". Reusing environment for sky." << LL_ENDL; -        environment->setSky(mCurrentEnvironment->getSky()); -        environment->setFlags(DayInstance::NO_ANIMATE_SKY); +        if (mCurrentEnvironment->getEnvironmentSelection() != ENV_NONE) +        { +            // Note: This looks suspicious. Shouldn't we assign whole day if mCurrentEnvironment has whole day? +            // and then add water/sky on top +            // This looks like it will result in sky using single keyframe instead of whole day if day is present +            // when setting static water without static sky +            environment->setSky(mCurrentEnvironment->getSky()); +            environment->setFlags(DayInstance::NO_ANIMATE_SKY); +        } +        else +        { +            // Environment is not properly initialized yet, but we should have environment by this point +            DayInstance::ptr_t substitute = getEnvironmentInstance(ENV_PARCEL, true); +            if (!substitute || !substitute->getSky()) +            { +                substitute = getEnvironmentInstance(ENV_REGION, true); +            } +            if (!substitute || !substitute->getSky()) +            { +                substitute = getEnvironmentInstance(ENV_DEFAULT, true); +            } + +            if (substitute && substitute->getSky()) +            { +                environment->setSky(substitute->getSky()); +                environment->setFlags(DayInstance::NO_ANIMATE_SKY); +            } +            else +            { +                LL_WARNS("ENVIRONMENT") << "Failed to assign substitute water/sky, environment is not properly initialized" << LL_ENDL; +            } +        }      }      if (fixed.second) @@ -1167,9 +1196,38 @@ void LLEnvironment::setEnvironment(LLEnvironment::EnvSelection_t env, LLEnvironm      }      else if (!environment->getWater())      { -        LL_DEBUGS("ENVIRONMENT") << "Blank water for " << env_selection_to_string(env) << ". Reusing environment for water." << LL_ENDL; -        environment->setWater(mCurrentEnvironment->getWater()); -        environment->setFlags(DayInstance::NO_ANIMATE_WATER); +        if (mCurrentEnvironment->getEnvironmentSelection() != ENV_NONE) +        { +            // Note: This looks suspicious. Shouldn't we assign whole day if mCurrentEnvironment has whole day? +            // and then add water/sky on top +            // This looks like it will result in water using single keyframe instead of whole day if day is present +            // when setting static sky without static water +            environment->setWater(mCurrentEnvironment->getWater()); +            environment->setFlags(DayInstance::NO_ANIMATE_WATER); +        } +        else +        { +            // Environment is not properly initialized yet, but we should have environment by this point +            DayInstance::ptr_t substitute = getEnvironmentInstance(ENV_PARCEL, true); +            if (!substitute || !substitute->getWater()) +            { +                substitute = getEnvironmentInstance(ENV_REGION, true); +            } +            if (!substitute || !substitute->getWater()) +            { +                substitute = getEnvironmentInstance(ENV_DEFAULT, true); +            } + +            if (substitute && substitute->getWater()) +            { +                environment->setWater(substitute->getWater()); +                environment->setFlags(DayInstance::NO_ANIMATE_WATER); +            } +            else +            { +                LL_WARNS("ENVIRONMENT") << "Failed to assign substitute water/sky, environment is not properly initialized" << LL_ENDL; +            } +        }      }      if (!mSignalEnvChanged.empty()) @@ -1217,28 +1275,24 @@ void LLEnvironment::setEnvironment(LLEnvironment::EnvSelection_t env, const LLSe  void LLEnvironment::setEnvironment(EnvSelection_t env, const LLUUID &assetId, S32 env_version)  { -    setEnvironment(env, assetId, LLSettingsDay::DEFAULT_DAYLENGTH, LLSettingsDay::DEFAULT_DAYOFFSET); +    setEnvironment(env, assetId, TRANSITION_DEFAULT, env_version);  } -  void LLEnvironment::setEnvironment(EnvSelection_t env,                                     const LLUUID &assetId, -                                   LLSettingsDay::Seconds daylength, -                                   LLSettingsDay::Seconds dayoffset, +                                   LLSettingsBase::Seconds transition,                                     S32 env_version)  {      LLSettingsVOBase::getSettingsAsset(assetId, -        [this, env, daylength, dayoffset, env_version](LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, LLExtStat) +        [this, env, env_version, transition](LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, LLExtStat)          { -            onSetEnvAssetLoaded(env, asset_id, settings, daylength, dayoffset, TRANSITION_DEFAULT, status, env_version); +            onSetEnvAssetLoaded(env, asset_id, settings, transition, status, env_version);          });  }  void LLEnvironment::onSetEnvAssetLoaded(EnvSelection_t env,                                          LLUUID asset_id,                                          LLSettingsBase::ptr_t settings, -                                        LLSettingsDay::Seconds daylength, -                                        LLSettingsDay::Seconds dayoffset,                                          LLSettingsBase::Seconds transition,                                          S32 status,                                          S32 env_version) @@ -1685,7 +1739,7 @@ void LLEnvironment::recordEnvironment(S32 parcel_id, LLEnvironment::EnvironmentI          if (!envinfo->mDayCycle)          {              clearEnvironment(ENV_PARCEL); -            setEnvironment(ENV_REGION, LLSettingsDay::GetDefaultAssetId(), LLSettingsDay::DEFAULT_DAYLENGTH, LLSettingsDay::DEFAULT_DAYOFFSET, envinfo->mEnvVersion); +            setEnvironment(ENV_REGION, LLSettingsDay::GetDefaultAssetId(), TRANSITION_DEFAULT, envinfo->mEnvVersion);              updateEnvironment();          }          else if (envinfo->mDayCycle->isTrackEmpty(LLSettingsDay::TRACK_WATER) @@ -1693,13 +1747,16 @@ void LLEnvironment::recordEnvironment(S32 parcel_id, LLEnvironment::EnvironmentI          {              LL_WARNS("ENVIRONMENT") << "Invalid day cycle for region" << LL_ENDL;              clearEnvironment(ENV_PARCEL); -            setEnvironment(ENV_REGION, LLSettingsDay::GetDefaultAssetId(), LLSettingsDay::DEFAULT_DAYLENGTH, LLSettingsDay::DEFAULT_DAYOFFSET, envinfo->mEnvVersion); +            setEnvironment(ENV_REGION, LLSettingsDay::GetDefaultAssetId(), TRANSITION_DEFAULT, envinfo->mEnvVersion);              updateEnvironment();          }          else          { -            setEnvironment(ENV_REGION, envinfo->mDayCycle, envinfo->mDayLength, envinfo->mDayOffset, envinfo->mEnvVersion);              mTrackAltitudes = envinfo->mAltitudes; +            // update track selection based on new altitudes +            mCurrentTrack = calculateSkyTrackForAltitude(gAgent.getPositionAgent().mV[VZ]); + +            setEnvironment(ENV_REGION, envinfo->mDayCycle, envinfo->mDayLength, envinfo->mDayOffset, envinfo->mEnvVersion);          }          LL_DEBUGS("ENVIRONMENT") << "Altitudes set to {" << mTrackAltitudes[0] << ", "<< mTrackAltitudes[1] << ", " << mTrackAltitudes[2] << ", " << mTrackAltitudes[3] << LL_ENDL; @@ -1931,6 +1988,10 @@ void LLEnvironment::coroRequestEnvironment(S32 parcel_id, LLEnvironment::environ      {          LL_WARNS("ENVIRONMENT") << "Couldn't retrieve environment settings for " << ((parcel_id == INVALID_PARCEL_ID) ? ("region!") : ("parcel!")) << LL_ENDL;      } +    else if (LLApp::isExiting()) +    { +        return; +    }      else      {          LLSD environment = result[KEY_ENVIRONMENT]; @@ -2020,6 +2081,10 @@ void LLEnvironment::coroUpdateEnvironment(S32 parcel_id, S32 track_no, UpdateInf          notify = LLSD::emptyMap();          notify["FAIL_REASON"] = result["message"].asString();      } +    else if (LLApp::isExiting()) +    { +        return; +    }      else      {          LLSD environment = result[KEY_ENVIRONMENT]; @@ -2082,6 +2147,10 @@ void LLEnvironment::coroResetEnvironment(S32 parcel_id, S32 track_no, environmen          notify = LLSD::emptyMap();          notify["FAIL_REASON"] = result["message"].asString();      } +    else if (LLApp::isExiting()) +    { +        return; +    }      else      {         LLSD environment = result[KEY_ENVIRONMENT]; @@ -2319,6 +2388,15 @@ void LLEnvironment::onAgentPositionHasChanged(const LLVector3 &localpos)          return;      mCurrentTrack = trackno; + +    LLViewerRegion* cur_region = gAgent.getRegion(); +    if (!cur_region || !cur_region->capabilitiesReceived()) +    { +        // Environment not ready, environment will be updated later, don't cause 'blend' yet. +        // But keep mCurrentTrack updated in case we won't get new altitudes for some reason +        return; +    } +      for (S32 env = ENV_LOCAL; env < ENV_DEFAULT; ++env)      {          if (mEnvironments[env]) @@ -2939,17 +3017,15 @@ bool LLEnvironment::loadFromSettings()      if (env_data.has("day_id"))      { -        LLSettingsDay::Seconds length = LLSettingsDay::Seconds(env_data["day_length"].asInteger()); -        LLSettingsDay::Seconds offset = LLSettingsDay::Seconds(env_data["day_offset"].asInteger());          LLUUID assetId = env_data["day_id"].asUUID();          LLSettingsVOBase::getSettingsAsset(assetId, -            [this, length, offset, env_data](LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, LLExtStat) +            [this, env_data](LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, LLExtStat)          {              // Day should be always applied first,              // otherwise it will override sky or water that was set earlier              // so wait for asset to load before applying sky/water -            onSetEnvAssetLoaded(ENV_LOCAL, asset_id, settings, length, offset, TRANSITION_DEFAULT, status, NO_VERSION); +            onSetEnvAssetLoaded(ENV_LOCAL, asset_id, settings, TRANSITION_DEFAULT, status, NO_VERSION);              bool valid = false, has_assets = false;              loadSkyWaterFromSettings(env_data, valid, has_assets);              if (!has_assets && valid) diff --git a/indra/newview/llenvironment.h b/indra/newview/llenvironment.h index 6ab0db7501..7cbf2d25bb 100644 --- a/indra/newview/llenvironment.h +++ b/indra/newview/llenvironment.h @@ -52,11 +52,11 @@ class LLEnvironment : public LLSingleton<LLEnvironment>      LOG_CLASS(LLEnvironment);  public: -    static const F32Seconds     TRANSITION_INSTANT; -    static const F32Seconds     TRANSITION_FAST; -    static const F32Seconds     TRANSITION_DEFAULT; -    static const F32Seconds     TRANSITION_SLOW; -    static const F32Seconds     TRANSITION_ALTITUDE; +    static const F64Seconds     TRANSITION_INSTANT; +    static const F64Seconds     TRANSITION_FAST; +    static const F64Seconds     TRANSITION_DEFAULT; +    static const F64Seconds     TRANSITION_SLOW; +    static const F64Seconds     TRANSITION_ALTITUDE;      static const LLUUID         KNOWN_SKY_SUNRISE;      static const LLUUID         KNOWN_SKY_MIDDAY; @@ -144,8 +144,8 @@ public:      void                        setEnvironment(EnvSelection_t env, const LLSettingsSky::ptr_t & fixed, S32 env_version = NO_VERSION) { setEnvironment(env, fixedEnvironment_t(fixed, LLSettingsWater::ptr_t()), env_version); }      void                        setEnvironment(EnvSelection_t env, const LLSettingsWater::ptr_t & fixed, S32 env_version = NO_VERSION) { setEnvironment(env, fixedEnvironment_t(LLSettingsSky::ptr_t(), fixed), env_version); }      void                        setEnvironment(EnvSelection_t env, const LLSettingsSky::ptr_t & fixeds, const LLSettingsWater::ptr_t & fixedw, S32 env_version = NO_VERSION) { setEnvironment(env, fixedEnvironment_t(fixeds, fixedw), env_version); } -    void                        setEnvironment(EnvSelection_t env, const LLUUID &assetId, LLSettingsDay::Seconds daylength, LLSettingsDay::Seconds dayoffset, S32 env_version = NO_VERSION); -    void                        setEnvironment(EnvSelection_t env, const LLUUID &assetId, S32 env_version = NO_VERSION); +    void                        setEnvironment(EnvSelection_t env, const LLUUID &assetId, S32 env_version); +    void                        setEnvironment(EnvSelection_t env, const LLUUID &assetId, LLSettingsBase::Seconds transition = TRANSITION_DEFAULT, S32 env_version = NO_VERSION);      void                        setSharedEnvironment();      void                        clearEnvironment(EnvSelection_t env); @@ -434,7 +434,7 @@ private:      void                        onAgentPositionHasChanged(const LLVector3 &localpos); -    void                        onSetEnvAssetLoaded(EnvSelection_t env, LLUUID asset_id, LLSettingsBase::ptr_t settings, LLSettingsDay::Seconds daylength, LLSettingsDay::Seconds dayoffset, LLSettingsBase::Seconds transition, S32 status, S32 env_version); +    void                        onSetEnvAssetLoaded(EnvSelection_t env, LLUUID asset_id, LLSettingsBase::ptr_t settings, LLSettingsBase::Seconds transition, S32 status, S32 env_version);      void                        onUpdateParcelAssetLoaded(LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, S32 parcel_id, S32 day_length, S32 day_offset, altitudes_vect_t altitudes);      void                        handleEnvironmentPushClear(LLUUID experience_id, LLSD &message, F32 transition); diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp index 7a887a2549..83b5bf3f25 100644 --- a/indra/newview/llfavoritesbar.cpp +++ b/indra/newview/llfavoritesbar.cpp @@ -38,6 +38,7 @@  #include "lltooltip.h"  #include "llagent.h" +#include "llagentpicksinfo.h"  #include "llavatarnamecache.h"  #include "llclipboard.h"  #include "llinventorybridge.h" @@ -403,6 +404,8 @@ LLFavoritesBarCtrl::LLFavoritesBarCtrl(const LLFavoritesBarCtrl::Params& p)  	mMoreTextBox = LLUICtrlFactory::create<LLTextBox> (more_button_params);  	mMoreTextBox->setClickedCallback(boost::bind(&LLFavoritesBarCtrl::onMoreTextBoxClicked, this));  	addChild(mMoreTextBox); +	LLRect rect = mMoreTextBox->getRect(); +	mMoreTextBox->setRect(LLRect(rect.mLeft - rect.getWidth(), rect.mTop, rect.mRight, rect.mBottom));  	mDropDownItemsCount = 0; @@ -1202,6 +1205,10 @@ bool LLFavoritesBarCtrl::enableSelected(const LLSD& userdata)      {          return isClipboardPasteable();      } +    else if (param == "create_pick") +    { +        return !LLAgentPicksInfo::getInstance()->isPickLimitReached(); +    }      return false;  } @@ -1250,6 +1257,13 @@ void LLFavoritesBarCtrl::doToSelected(const LLSD& userdata)  			LLFloaterReg::showInstance("world_map", "center");  		}  	} +    else if (action == "create_pick") +    { +        LLSD args; +        args["type"] = "create_pick"; +        args["item_id"] = item->getUUID(); +        LLFloaterSidePanelContainer::showPanel("places", args); +    }  	else if (action == "cut")  	{  	} @@ -1265,6 +1279,20 @@ void LLFavoritesBarCtrl::doToSelected(const LLSD& userdata)  	{  		gInventory.removeItem(mSelectedItemID);  	} +    else if (action == "rename") +    { +        LLSD args; +        args["NAME"] = item->getName(); + +        LLSD payload; +        payload["id"] = mSelectedItemID; + +        LLNotificationsUtil::add("RenameLandmark", args, payload, boost::bind(onRenameCommit, _1, _2)); +    } +	else if (action == "move_to_landmarks") +	{ +		change_item_parent(mSelectedItemID, gInventory.findCategoryUUIDForType(LLFolderType::FT_LANDMARK)); +	}  	// Pop-up the overflow menu again (it gets hidden whenever the user clicks a context menu item).  	// See EXT-4217 and STORM-207. @@ -1277,6 +1305,28 @@ void LLFavoritesBarCtrl::doToSelected(const LLSD& userdata)  	}  } +bool LLFavoritesBarCtrl::onRenameCommit(const LLSD& notification, const LLSD& response) +{ +    S32 option = LLNotificationsUtil::getSelectedOption(notification, response); +    if (0 == option) +    { +        LLUUID id = notification["payload"]["id"].asUUID(); +        LLInventoryItem *item = gInventory.getItem(id); +        std::string landmark_name = response["new_name"].asString(); +        LLStringUtil::trim(landmark_name); + +        if (!landmark_name.empty() && item && item->getName() != landmark_name) +        { +            LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item); +            new_item->rename(landmark_name); +            new_item->updateServer(FALSE); +            gInventory.updateItem(new_item); +        } +    } + +    return false; +} +  BOOL LLFavoritesBarCtrl::isClipboardPasteable() const  {  	if (!LLClipboard::instance().hasContents()) diff --git a/indra/newview/llfavoritesbar.h b/indra/newview/llfavoritesbar.h index 868f1c83c8..3bb940948b 100644 --- a/indra/newview/llfavoritesbar.h +++ b/indra/newview/llfavoritesbar.h @@ -91,6 +91,7 @@ protected:  	bool enableSelected(const LLSD& userdata);  	void doToSelected(const LLSD& userdata); +	static bool onRenameCommit(const LLSD& notification, const LLSD& response);  	BOOL isClipboardPasteable() const;  	void pasteFromClipboard() const; diff --git a/indra/newview/llfloaterabout.cpp b/indra/newview/llfloaterabout.cpp index 171858e472..1fbd198019 100644 --- a/indra/newview/llfloaterabout.cpp +++ b/indra/newview/llfloaterabout.cpp @@ -236,6 +236,7 @@ void LLFloaterAbout::fetchServerReleaseNotesCoro(const std::string& cap_url)      httpOpts->setWantHeaders(true);      httpOpts->setFollowRedirects(false); +    httpOpts->setSSLVerifyPeer(false); // We want this data even if SSL verification fails      LLSD result = httpAdapter->getAndSuspend(httpRequest, cap_url, httpOpts); diff --git a/indra/newview/llfloateraddpaymentmethod.cpp b/indra/newview/llfloateraddpaymentmethod.cpp new file mode 100644 index 0000000000..3952b48229 --- /dev/null +++ b/indra/newview/llfloateraddpaymentmethod.cpp @@ -0,0 +1,81 @@ +/**  + * @file llfloateraddpaymentmethod.cpp + * @brief LLFloaterAddPaymentMethod class implementation + * + * $LicenseInfo:firstyear=2020&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2020, 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 "llfloateraddpaymentmethod.h" +#include "llnotificationsutil.h" +#include "lluictrlfactory.h" +#include "llweb.h" + + +LLFloaterAddPaymentMethod::LLFloaterAddPaymentMethod(const LLSD& key) +	:	LLFloater(key) +{ +} + +LLFloaterAddPaymentMethod::~LLFloaterAddPaymentMethod() +{ +} + +BOOL LLFloaterAddPaymentMethod::postBuild() +{ +	setCanDrag(FALSE); +	getChild<LLButton>("continue_btn")->setCommitCallback(boost::bind(&LLFloaterAddPaymentMethod::onContinueBtn, this)); +	getChild<LLButton>("close_btn")->setCommitCallback(boost::bind(&LLFloaterAddPaymentMethod::onCloseBtn, this)); +	return TRUE; +} + +void LLFloaterAddPaymentMethod::onOpen(const LLSD& key) +{ +	centerOnScreen(); +} + +void LLFloaterAddPaymentMethod::onContinueBtn() +{ +	closeFloater(); +	LLNotificationsUtil::add("AddPaymentMethod", LLSD(), LLSD(), +		[this](const LLSD¬if, const LLSD&resp) +	{ +		S32 opt = LLNotificationsUtil::getSelectedOption(notif, resp); +		if (opt == 0) +		{ +			LLWeb::loadURL(this->getString("continue_url")); +		} +	});  +} + +void LLFloaterAddPaymentMethod::onCloseBtn() +{ +	closeFloater(); +} + +void LLFloaterAddPaymentMethod::centerOnScreen() +{ +	LLVector2 window_size = LLUI::getInstance()->getWindowSize(); +	centerWithin(LLRect(0, 0, ll_round(window_size.mV[VX]), ll_round(window_size.mV[VY]))); +} + diff --git a/indra/newview/llfloateraddpaymentmethod.h b/indra/newview/llfloateraddpaymentmethod.h new file mode 100644 index 0000000000..b3bb624484 --- /dev/null +++ b/indra/newview/llfloateraddpaymentmethod.h @@ -0,0 +1,52 @@ +/**  + * @file llfloateraddpaymentmethod.h + * @brief LLFloaterAddPaymentMethod class definition + * + * $LicenseInfo:firstyear=2020&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2020, 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_FLOATER_ADDPAYMENTMETHOD_H +#define LL_FLOATER_ADDPAYMENTMETHOD_H + +#include "llfloater.h" + +class LLFloaterAddPaymentMethod: +	public LLFloater +{ +	friend class LLFloaterReg; +public: +	/*virtual*/	BOOL postBuild(); +	/*virtual*/ void onOpen(const LLSD& key); + +private: +	LLFloaterAddPaymentMethod(const LLSD& key); + +	void centerOnScreen(); + +	void onCloseBtn(); +	void onContinueBtn(); +	 +	/*virtual*/	~LLFloaterAddPaymentMethod(); + +}; + +#endif diff --git a/indra/newview/llfloaterbuycurrency.cpp b/indra/newview/llfloaterbuycurrency.cpp index 1751d54b5a..0cfac166c7 100644 --- a/indra/newview/llfloaterbuycurrency.cpp +++ b/indra/newview/llfloaterbuycurrency.cpp @@ -32,6 +32,8 @@  #include "llcurrencyuimanager.h"  #include "llfloater.h"  #include "llfloaterreg.h" +#include "lllayoutstack.h" +#include "lliconctrl.h"  #include "llnotificationsutil.h"  #include "llstatusbar.h"  #include "lltextbox.h" @@ -42,7 +44,6 @@  #include "llwindow.h"  #include "llappviewer.h" -static const S32 STANDARD_BUY_AMOUNT = 2000;  static const S32 MINIMUM_BALANCE_AMOUNT = 0;  class LLFloaterBuyCurrencyUI @@ -58,8 +59,8 @@ public:  	LLCurrencyUIManager	mManager;  	bool		mHasTarget; -	std::string	mTargetName;  	S32			mTargetPrice; +	S32			mRequiredAmount;  public:  	void noTarget(); @@ -68,6 +69,7 @@ public:  	virtual BOOL postBuild();  	void updateUI(); +	void collapsePanels(bool collapse);  	virtual void draw();  	virtual BOOL canClose(); @@ -92,7 +94,9 @@ LLFloater* LLFloaterBuyCurrency::buildFloater(const LLSD& key)  LLFloaterBuyCurrencyUI::LLFloaterBuyCurrencyUI(const LLSD& key)  :	LLFloater(key),  	mChildren(*this), -	mManager(*this) +	mManager(*this), +	mHasTarget(false), +	mTargetPrice(0)  {  } @@ -104,15 +108,20 @@ LLFloaterBuyCurrencyUI::~LLFloaterBuyCurrencyUI()  void LLFloaterBuyCurrencyUI::noTarget()  {  	mHasTarget = false; -	mManager.setAmount(STANDARD_BUY_AMOUNT); +	mTargetPrice = 0; +	mManager.setAmount(0);  }  void LLFloaterBuyCurrencyUI::target(const std::string& name, S32 price)  {  	mHasTarget = true; -	mTargetName = name;  	mTargetPrice = price; +	if (!name.empty()) +	{ +		getChild<LLUICtrl>("target_price_label")->setValue(name); +	} +  	S32 balance = gStatusBar->getBalance();  	S32 need = price - balance;  	if (need < 0) @@ -120,7 +129,8 @@ void LLFloaterBuyCurrencyUI::target(const std::string& name, S32 price)  		need = 0;  	} -	mManager.setAmount(need + MINIMUM_BALANCE_AMOUNT); +	mRequiredAmount = need + MINIMUM_BALANCE_AMOUNT; +	mManager.setAmount(0);  } @@ -175,7 +185,6 @@ void LLFloaterBuyCurrencyUI::updateUI()  	getChildView("purchase_warning_repurchase")->setVisible(FALSE);  	getChildView("purchase_warning_notenough")->setVisible(FALSE);  	getChildView("contacting")->setVisible(FALSE); -	getChildView("buy_action")->setVisible(FALSE);  	if (hasError)  	{ @@ -209,8 +218,8 @@ void LLFloaterBuyCurrencyUI::updateUI()  		{  			if (mHasTarget)  			{ -				getChildView("buy_action")->setVisible( true); -				getChild<LLUICtrl>("buy_action")->setTextArg("[ACTION]", mTargetName); +				getChild<LLUICtrl>("target_price")->setTextArg("[AMT]", llformat("%d", mTargetPrice)); +				getChild<LLUICtrl>("required_amount")->setTextArg("[AMT]", llformat("%d", mRequiredAmount));  			}  		} @@ -231,18 +240,40 @@ void LLFloaterBuyCurrencyUI::updateUI()  		if (mHasTarget)  		{ -			if (total >= mTargetPrice) -			{ -				getChildView("purchase_warning_repurchase")->setVisible( true); -			} -			else -			{ -				getChildView("purchase_warning_notenough")->setVisible( true); -			} +			getChildView("purchase_warning_repurchase")->setVisible( !getChildView("currency_links")->getVisible());  		}  	} -	getChildView("getting_data")->setVisible( !mManager.canBuy() && !hasError); +	getChildView("getting_data")->setVisible( !mManager.canBuy() && !hasError && !getChildView("currency_est")->getVisible()); +} + +void LLFloaterBuyCurrencyUI::collapsePanels(bool collapse) +{ +	LLLayoutPanel* price_panel = getChild<LLLayoutPanel>("layout_panel_price"); +	 +	if (price_panel->isCollapsed() == collapse) +		return; +	 +	LLLayoutStack* outer_stack = getChild<LLLayoutStack>("outer_stack");	 +	LLLayoutPanel* required_panel = getChild<LLLayoutPanel>("layout_panel_required"); +	LLLayoutPanel* msg_panel = getChild<LLLayoutPanel>("layout_panel_msg"); + +	S32 delta_height = price_panel->getRect().getHeight() + required_panel->getRect().getHeight() + msg_panel->getRect().getHeight(); +	delta_height *= (collapse ? -1 : 1); + +	LLIconCtrl* icon = getChild<LLIconCtrl>("normal_background"); +	LLRect rect = icon->getRect(); +	icon->setRect(rect.setOriginAndSize(rect.mLeft, rect.mBottom - delta_height, rect.getWidth(), rect.getHeight() + delta_height)); + +	outer_stack->collapsePanel(price_panel, collapse); +	outer_stack->collapsePanel(required_panel, collapse); +	outer_stack->collapsePanel(msg_panel, collapse); + +	outer_stack->updateLayout(); + +	LLRect floater_rect = getRect(); +	floater_rect.mBottom -= delta_height; +	setShape(floater_rect, false);  }  void LLFloaterBuyCurrencyUI::onClickBuy() @@ -260,20 +291,72 @@ void LLFloaterBuyCurrencyUI::onClickCancel()  	LLStatusBar::sendMoneyBalanceRequest();  } +LLFetchAvatarPaymentInfo* LLFloaterBuyCurrency::sPropertiesRequest = NULL; +  // static  void LLFloaterBuyCurrency::buyCurrency()  { -	LLFloaterBuyCurrencyUI* ui = LLFloaterReg::showTypedInstance<LLFloaterBuyCurrencyUI>("buy_currency"); -	ui->noTarget(); -	ui->updateUI(); +	delete sPropertiesRequest; +	sPropertiesRequest = new LLFetchAvatarPaymentInfo(false);  }  // static  void LLFloaterBuyCurrency::buyCurrency(const std::string& name, S32 price)  { -	LLFloaterBuyCurrencyUI* ui = LLFloaterReg::showTypedInstance<LLFloaterBuyCurrencyUI>("buy_currency"); -	ui->target(name, price); -	ui->updateUI(); +	delete sPropertiesRequest; +	sPropertiesRequest = new LLFetchAvatarPaymentInfo(true, name, price); +} + +// static +void LLFloaterBuyCurrency::handleBuyCurrency(bool has_piof, bool has_target, const std::string name, S32 price) +{ +	delete sPropertiesRequest; +	sPropertiesRequest = NULL; + +	if (has_piof) +	{ +		LLFloaterBuyCurrencyUI* ui = LLFloaterReg::showTypedInstance<LLFloaterBuyCurrencyUI>("buy_currency"); +		if (has_target) +		{ +			ui->target(name, price); +		} +		else +		{ +			ui->noTarget();			 +		} +		ui->updateUI(); +		ui->collapsePanels(!has_target); +	} +	else +	{ +		LLFloaterReg::showInstance("add_payment_method"); +	}  } +LLFetchAvatarPaymentInfo::LLFetchAvatarPaymentInfo(bool has_target, const std::string& name, S32 price) +:	mAvatarID(gAgent.getID()), +	mHasTarget(has_target), +	mPrice(price), +	mName(name) +{ +	LLAvatarPropertiesProcessor* processor = LLAvatarPropertiesProcessor::getInstance(); +	// register ourselves as an observer +	processor->addObserver(mAvatarID, this); +	// send a request (duplicates will be suppressed inside the avatar +	// properties processor) +	processor->sendAvatarPropertiesRequest(mAvatarID); +} + +LLFetchAvatarPaymentInfo::~LLFetchAvatarPaymentInfo() +{ +	LLAvatarPropertiesProcessor::getInstance()->removeObserver(mAvatarID, this); +} +void LLFetchAvatarPaymentInfo::processProperties(void* data, EAvatarProcessorType type) +{ +	if (data && type == APT_PROPERTIES) +	{ +		LLAvatarData* avatar_data = static_cast<LLAvatarData*>(data); +		LLFloaterBuyCurrency::handleBuyCurrency(LLAvatarPropertiesProcessor::hasPaymentInfoOnFile(avatar_data), mHasTarget, mName, mPrice); +	} +} diff --git a/indra/newview/llfloaterbuycurrency.h b/indra/newview/llfloaterbuycurrency.h index 7ff6c42384..88d3d17cd6 100644 --- a/indra/newview/llfloaterbuycurrency.h +++ b/indra/newview/llfloaterbuycurrency.h @@ -27,15 +27,34 @@  #ifndef LL_LLFLOATERBUYCURRENCY_H  #define LL_LLFLOATERBUYCURRENCY_H +#include "llavatarpropertiesprocessor.h"  #include "stdtypes.h" - +#include "llagent.h"  class LLFloater; +class LLFetchAvatarPaymentInfo : public LLAvatarPropertiesObserver +{ +public: +	LLFetchAvatarPaymentInfo(bool has_target, const std::string& name = std::string(), S32 price = 0); +	~LLFetchAvatarPaymentInfo(); + +	void processProperties(void* data, EAvatarProcessorType type); + +private: +	LLUUID mAvatarID; +	bool mHasTarget; +	std::string mName; +    S32 mPrice; +}; + +  class LLFloaterBuyCurrency  {  public:  	static void buyCurrency();  	static void buyCurrency(const std::string& name, S32 price); + +		static void handleBuyCurrency(bool has_piof, bool has_target, const std::string name, S32 price);  		/* name should be a noun phrase of the object or service being bought:  				"That object costs"  				"Trying to give" @@ -44,7 +63,8 @@ public:  		*/  	static LLFloater* buildFloater(const LLSD& key); -}; +	static LLFetchAvatarPaymentInfo* sPropertiesRequest; +};  #endif diff --git a/indra/newview/llfloatercreatelandmark.cpp b/indra/newview/llfloatercreatelandmark.cpp new file mode 100644 index 0000000000..6b1d9306fb --- /dev/null +++ b/indra/newview/llfloatercreatelandmark.cpp @@ -0,0 +1,323 @@ +/**  + * @file llfloatercreatelandmark.cpp + * @brief LLFloaterCreateLandmark class implementation + * + * $LicenseInfo:firstyear=2021&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2021, 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 "llfloatercreatelandmark.h" + +#include "llagent.h" +#include "llagentui.h" +#include "llcombobox.h" +#include "llinventoryfunctions.h" +#include "llinventoryobserver.h" +#include "lllandmarkactions.h" +#include "llnotificationsutil.h" +#include "llpanellandmarkinfo.h" +#include "llparcel.h" +#include "lltextbox.h" +#include "lltexteditor.h" +#include "lluictrlfactory.h" +#include "llviewermessage.h" +#include "llviewerparcelmgr.h" +#include "llviewerregion.h" + +typedef std::pair<LLUUID, std::string> folder_pair_t; + +class LLLandmarksInventoryObserver : public LLInventoryAddedObserver +{ +public: +	LLLandmarksInventoryObserver(LLFloaterCreateLandmark* create_landmark_floater) : +		mFloater(create_landmark_floater) +	{} + +protected: +	/*virtual*/ void done() +	{ +		mFloater->setItem(gInventory.getAddedIDs()); +	} + +private: +	LLFloaterCreateLandmark* mFloater; +}; + +LLFloaterCreateLandmark::LLFloaterCreateLandmark(const LLSD& key) +	:	LLFloater("add_landmark"), +		mItem(NULL) +{ +	mInventoryObserver = new LLLandmarksInventoryObserver(this); +} + +LLFloaterCreateLandmark::~LLFloaterCreateLandmark() +{ +	removeObserver(); +} + +BOOL LLFloaterCreateLandmark::postBuild() +{ +	mFolderCombo = getChild<LLComboBox>("folder_combo"); +	mLandmarkTitleEditor = getChild<LLLineEditor>("title_editor"); +	mNotesEditor = getChild<LLTextEditor>("notes_editor"); + +	getChild<LLTextBox>("new_folder_textbox")->setURLClickedCallback(boost::bind(&LLFloaterCreateLandmark::onCreateFolderClicked, this)); +	getChild<LLButton>("ok_btn")->setClickedCallback(boost::bind(&LLFloaterCreateLandmark::onSaveClicked, this)); +	getChild<LLButton>("cancel_btn")->setClickedCallback(boost::bind(&LLFloaterCreateLandmark::onCancelClicked, this)); + +	mLandmarksID = gInventory.findCategoryUUIDForType(LLFolderType::FT_LANDMARK); + +	return TRUE; +} + +void LLFloaterCreateLandmark::removeObserver() +{ +	if (gInventory.containsObserver(mInventoryObserver)) +		gInventory.removeObserver(mInventoryObserver); +} + +void LLFloaterCreateLandmark::onOpen(const LLSD& key) +{ +	LLUUID dest_folder = LLUUID(); +	if (key.has("dest_folder")) +	{ +		dest_folder = key["dest_folder"].asUUID(); +	} +	mItem = NULL; +	gInventory.addObserver(mInventoryObserver); +	setLandmarkInfo(dest_folder); +	populateFoldersList(dest_folder); +} + +void LLFloaterCreateLandmark::setLandmarkInfo(const LLUUID &folder_id) +{ +	LLViewerParcelMgr* parcel_mgr = LLViewerParcelMgr::getInstance(); +	LLParcel* parcel = parcel_mgr->getAgentParcel(); +	std::string name = parcel->getName(); +	LLVector3 agent_pos = gAgent.getPositionAgent(); + +	if (name.empty()) +	{ +		S32 region_x = ll_round(agent_pos.mV[VX]); +		S32 region_y = ll_round(agent_pos.mV[VY]); +		S32 region_z = ll_round(agent_pos.mV[VZ]); + +		std::string region_name; +		LLViewerRegion* region = parcel_mgr->getSelectionRegion(); +		if (region) +		{ +			region_name = region->getName(); +		} +		else +		{ +			std::string desc; +			LLAgentUI::buildLocationString(desc, LLAgentUI::LOCATION_FORMAT_NORMAL, agent_pos); +			region_name = desc; +		} + +		mLandmarkTitleEditor->setText(llformat("%s (%d, %d, %d)", +			region_name.c_str(), region_x, region_y, region_z)); +	} +	else +	{ +		mLandmarkTitleEditor->setText(name); +	} + +	LLLandmarkActions::createLandmarkHere(name, "", folder_id.notNull() ? folder_id : gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE)); +} + +bool cmp_folders(const folder_pair_t& left, const folder_pair_t& right) +{ +	return left.second < right.second; +} + +void LLFloaterCreateLandmark::populateFoldersList(const LLUUID &folder_id) +{ +	// Collect all folders that can contain landmarks. +	LLInventoryModel::cat_array_t cats; +	LLPanelLandmarkInfo::collectLandmarkFolders(cats); + +	mFolderCombo->removeall(); + +	// Put the "My Favorites" folder first in list. +	LLUUID favorites_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE); +	LLViewerInventoryCategory* favorites_cat = gInventory.getCategory(favorites_id); +	if (!favorites_cat) +	{ +		LL_WARNS() << "Cannot find the favorites folder" << LL_ENDL; +	} +	else +	{ +		mFolderCombo->add(getString("favorites_bar"), favorites_cat->getUUID()); +	} + +	// Add the "Landmarks" category.  +	const LLViewerInventoryCategory* lmcat = gInventory.getCategory(mLandmarksID); +	if (!lmcat) +	{ +		LL_WARNS() << "Cannot find the landmarks folder" << LL_ENDL; +	} +	else +	{ +		std::string cat_full_name = LLPanelLandmarkInfo::getFullFolderName(lmcat); +		mFolderCombo->add(cat_full_name, lmcat->getUUID()); +	} + +	typedef std::vector<folder_pair_t> folder_vec_t; +	folder_vec_t folders; +	// Sort the folders by their full name. +	for (S32 i = 0; i < cats.size(); i++) +	{ +		const LLViewerInventoryCategory* cat = cats.at(i); +		std::string cat_full_name = LLPanelLandmarkInfo::getFullFolderName(cat); +		folders.push_back(folder_pair_t(cat->getUUID(), cat_full_name)); +	} +	sort(folders.begin(), folders.end(), cmp_folders); + +	// Finally, populate the combobox. +	for (folder_vec_t::const_iterator it = folders.begin(); it != folders.end(); it++) +		mFolderCombo->add(it->second, LLSD(it->first)); + +	if (folder_id.notNull()) +	{ +		mFolderCombo->setCurrentByID(folder_id); +	} +} + +void LLFloaterCreateLandmark::onCreateFolderClicked() +{ +	LLNotificationsUtil::add("CreateLandmarkFolder", LLSD(), LLSD(), +		[this](const LLSD¬if, const LLSD&resp) +	{ +		S32 opt = LLNotificationsUtil::getSelectedOption(notif, resp); +		if (opt == 0) +		{ +			std::string folder_name = resp["message"].asString(); +			if (!folder_name.empty()) +			{ +				inventory_func_type func = boost::bind(&LLFloaterCreateLandmark::folderCreatedCallback, this, _1); +				gInventory.createNewCategory(mLandmarksID, LLFolderType::FT_NONE, folder_name, func); +				gInventory.notifyObservers(); +			} +		} +	});  +} + +void LLFloaterCreateLandmark::folderCreatedCallback(LLUUID folder_id) +{ +	populateFoldersList(folder_id); +} + +void LLFloaterCreateLandmark::onSaveClicked() +{ +	if (mItem.isNull()) +	{ +		closeFloater(); +		return; +	} +		 + +	std::string current_title_value = mLandmarkTitleEditor->getText(); +	std::string item_title_value = mItem->getName(); +	std::string current_notes_value = mNotesEditor->getText(); +	std::string item_notes_value = mItem->getDescription(); + +	LLStringUtil::trim(current_title_value); +	LLStringUtil::trim(current_notes_value); + +	LLUUID item_id = mItem->getUUID(); +	LLUUID folder_id = mFolderCombo->getValue().asUUID(); +	bool change_parent = folder_id != mItem->getParentUUID(); + +	LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(mItem); + +	if (!current_title_value.empty() && +		(item_title_value != current_title_value || item_notes_value != current_notes_value)) +	{ +		new_item->rename(current_title_value); +		new_item->setDescription(current_notes_value); +		LLPointer<LLInventoryCallback> cb; +		if (change_parent) +		{ +			cb = new LLUpdateLandmarkParent(new_item, folder_id); +		} +		LLInventoryModel::LLCategoryUpdate up(mItem->getParentUUID(), 0); +		gInventory.accountForUpdate(up); +		update_inventory_item(new_item, cb); +	} +	else if (change_parent) +	{ +		LLInventoryModel::update_list_t update; +		LLInventoryModel::LLCategoryUpdate old_folder(mItem->getParentUUID(),-1); +		update.push_back(old_folder); +		LLInventoryModel::LLCategoryUpdate new_folder(folder_id, 1); +		update.push_back(new_folder); +		gInventory.accountForUpdate(update); + +		new_item->setParent(folder_id); +		new_item->updateParentOnServer(FALSE); +	} + +	gInventory.updateItem(new_item); +	gInventory.notifyObservers(); + +	closeFloater(); +} + +void LLFloaterCreateLandmark::onCancelClicked() +{ +	if (!mItem.isNull()) +	{ +		LLUUID item_id = mItem->getUUID(); +		remove_inventory_item(item_id, NULL); +	} +	closeFloater(); +} + + +void LLFloaterCreateLandmark::setItem(const uuid_set_t& items) +{ +	for (uuid_set_t::const_iterator item_iter = items.begin(); +		item_iter != items.end(); +		++item_iter) +	{ +		const LLUUID& item_id = (*item_iter); +		if(!highlight_offered_object(item_id)) +		{ +			continue; +		} + +		LLInventoryItem* item = gInventory.getItem(item_id); + +		llassert(item); +		if (item && (LLAssetType::AT_LANDMARK == item->getType()) ) +		{ +			if(!getItem()) +			{ +				removeObserver(); +				mItem = item; +				break; +			} +		} +	} +} diff --git a/indra/newview/llfloatercreatelandmark.h b/indra/newview/llfloatercreatelandmark.h new file mode 100644 index 0000000000..74ac5e651c --- /dev/null +++ b/indra/newview/llfloatercreatelandmark.h @@ -0,0 +1,74 @@ +/**  + * @file llfloatercreatelandmark.h + * @brief LLFloaterCreateLandmark class definition + * + * $LicenseInfo:firstyear=2021&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2021, 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_LLFLOATERCREATELANDMARK_H +#define LL_LLFLOATERCREATELANDMARK_H + +#include "llfloater.h" + +class LLComboBox; +class LLInventoryItem; +class LLLineEditor; +class LLTextEditor; +class LLLandmarksInventoryObserver; + +class LLFloaterCreateLandmark: +	public LLFloater +{ +	friend class LLFloaterReg; + +public: + +	LLFloaterCreateLandmark(const LLSD& key); +	~LLFloaterCreateLandmark(); + +	BOOL postBuild(); +	void onOpen(const LLSD& key); + +	void setItem(const uuid_set_t& items); + +	LLInventoryItem* getItem() { return mItem; } + +private: +	void setLandmarkInfo(const LLUUID &folder_id); +	void removeObserver(); +	void populateFoldersList(const LLUUID &folder_id = LLUUID::null); +	void onCreateFolderClicked(); +	void onSaveClicked(); +	void onCancelClicked(); + +	void folderCreatedCallback(LLUUID folder_id); + +	LLComboBox*		mFolderCombo; +	LLLineEditor*	mLandmarkTitleEditor; +	LLTextEditor*	mNotesEditor; +	LLUUID			mLandmarksID; + +	LLLandmarksInventoryObserver*	mInventoryObserver; +	LLPointer<LLInventoryItem>		mItem; +}; + +#endif diff --git a/indra/newview/llfloatereditenvironmentbase.cpp b/indra/newview/llfloatereditenvironmentbase.cpp index e888144b6a..2850951668 100644 --- a/indra/newview/llfloatereditenvironmentbase.cpp +++ b/indra/newview/llfloatereditenvironmentbase.cpp @@ -262,7 +262,7 @@ void LLFloaterEditEnvironmentBase::onSaveAsCommit(const LLSD& notification, cons          {              const LLUUID &marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false);              LLUUID parent_id = mInventoryItem->getParentUUID(); -            if (marketplacelistings_id == parent_id) +            if (marketplacelistings_id == parent_id || gInventory.isObjectDescendentOf(mInventoryItem->getUUID(), gInventory.getLibraryRootFolderID()))              {                  parent_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS);              } diff --git a/indra/newview/llfloaterenvironmentadjust.cpp b/indra/newview/llfloaterenvironmentadjust.cpp index 4eb5e03603..95d6a2d652 100644 --- a/indra/newview/llfloaterenvironmentadjust.cpp +++ b/indra/newview/llfloaterenvironmentadjust.cpp @@ -53,11 +53,15 @@ namespace      const std::string FIELD_SKY_CLOUD_SCALE("cloud_scale");      const std::string FIELD_SKY_SCENE_GAMMA("scene_gamma");      const std::string FIELD_SKY_SUN_ROTATION("sun_rotation"); +    const std::string FIELD_SKY_SUN_AZIMUTH("sun_azimuth"); +    const std::string FIELD_SKY_SUN_ELEVATION("sun_elevation");      const std::string FIELD_SKY_SUN_SCALE("sun_scale");      const std::string FIELD_SKY_GLOW_FOCUS("glow_focus");      const std::string FIELD_SKY_GLOW_SIZE("glow_size");      const std::string FIELD_SKY_STAR_BRIGHTNESS("star_brightness");      const std::string FIELD_SKY_MOON_ROTATION("moon_rotation"); +    const std::string FIELD_SKY_MOON_AZIMUTH("moon_azimuth"); +    const std::string FIELD_SKY_MOON_ELEVATION("moon_elevation");      const std::string BTN_RESET("btn_reset");      const F32 SLIDER_SCALE_SUN_AMBIENT(3.0f); @@ -96,9 +100,13 @@ BOOL LLFloaterEnvironmentAdjust::postBuild()      getChild<LLUICtrl>(FIELD_SKY_GLOW_SIZE)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onGlowChanged(); });      getChild<LLUICtrl>(FIELD_SKY_STAR_BRIGHTNESS)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onStarBrightnessChanged(); });      getChild<LLUICtrl>(FIELD_SKY_SUN_ROTATION)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onSunRotationChanged(); }); +    getChild<LLUICtrl>(FIELD_SKY_SUN_AZIMUTH)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onSunAzimElevChanged(); }); +    getChild<LLUICtrl>(FIELD_SKY_SUN_ELEVATION)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onSunAzimElevChanged(); });      getChild<LLUICtrl>(FIELD_SKY_SUN_SCALE)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onSunScaleChanged(); });      getChild<LLUICtrl>(FIELD_SKY_MOON_ROTATION)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onMoonRotationChanged(); }); +    getChild<LLUICtrl>(FIELD_SKY_MOON_AZIMUTH)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onMoonAzimElevChanged(); }); +    getChild<LLUICtrl>(FIELD_SKY_MOON_ELEVATION)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onMoonAzimElevChanged(); });      getChild<LLUICtrl>(BTN_RESET)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onButtonReset(); });      getChild<LLTextureCtrl>(FIELD_SKY_CLOUD_MAP)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onCloudMapChanged(); }); @@ -169,10 +177,25 @@ void LLFloaterEnvironmentAdjust::refresh()      getChild<LLUICtrl>(FIELD_SKY_GLOW_SIZE)->setValue(2.0 - (glow.mV[0] / SLIDER_SCALE_GLOW_R));      getChild<LLUICtrl>(FIELD_SKY_GLOW_FOCUS)->setValue(glow.mV[2] / SLIDER_SCALE_GLOW_B);      getChild<LLUICtrl>(FIELD_SKY_STAR_BRIGHTNESS)->setValue(mLiveSky->getStarBrightness()); -    getChild<LLVirtualTrackball>(FIELD_SKY_SUN_ROTATION)->setRotation(mLiveSky->getSunRotation());      getChild<LLUICtrl>(FIELD_SKY_SUN_SCALE)->setValue(mLiveSky->getSunScale()); -    getChild<LLVirtualTrackball>(FIELD_SKY_MOON_ROTATION)->setRotation(mLiveSky->getMoonRotation()); +    // Sun rotation +    LLQuaternion quat = mLiveSky->getSunRotation(); +    F32 azimuth; +    F32 elevation; +    LLVirtualTrackball::getAzimuthAndElevationDeg(quat, azimuth, elevation); + +    getChild<LLUICtrl>(FIELD_SKY_SUN_AZIMUTH)->setValue(azimuth); +    getChild<LLUICtrl>(FIELD_SKY_SUN_ELEVATION)->setValue(elevation); +    getChild<LLVirtualTrackball>(FIELD_SKY_SUN_ROTATION)->setRotation(quat); + +    // Moon rotation +    quat = mLiveSky->getMoonRotation(); +    LLVirtualTrackball::getAzimuthAndElevationDeg(quat, azimuth, elevation); + +    getChild<LLUICtrl>(FIELD_SKY_MOON_AZIMUTH)->setValue(azimuth); +    getChild<LLUICtrl>(FIELD_SKY_MOON_ELEVATION)->setValue(elevation); +    getChild<LLVirtualTrackball>(FIELD_SKY_MOON_ROTATION)->setRotation(quat);  } @@ -325,10 +348,45 @@ void LLFloaterEnvironmentAdjust::onStarBrightnessChanged()  void LLFloaterEnvironmentAdjust::onSunRotationChanged()  { -    if (!mLiveSky) -        return; -    mLiveSky->setSunRotation(getChild<LLVirtualTrackball>(FIELD_SKY_SUN_ROTATION)->getRotation()); -    mLiveSky->update(); +    LLQuaternion quat = getChild<LLVirtualTrackball>(FIELD_SKY_SUN_ROTATION)->getRotation(); +    F32 azimuth; +    F32 elevation; +    LLVirtualTrackball::getAzimuthAndElevationDeg(quat, azimuth, elevation); +    getChild<LLUICtrl>(FIELD_SKY_SUN_AZIMUTH)->setValue(azimuth); +    getChild<LLUICtrl>(FIELD_SKY_SUN_ELEVATION)->setValue(elevation); +    if (mLiveSky) +    { +        mLiveSky->setSunRotation(quat); +        mLiveSky->update(); +    } +} + +void LLFloaterEnvironmentAdjust::onSunAzimElevChanged() +{ +    F32 azimuth = getChild<LLUICtrl>(FIELD_SKY_SUN_AZIMUTH)->getValue().asReal(); +    F32 elevation = getChild<LLUICtrl>(FIELD_SKY_SUN_ELEVATION)->getValue().asReal(); +    LLQuaternion quat; + +    azimuth *= DEG_TO_RAD; +    elevation *= DEG_TO_RAD; + +    if (is_approx_zero(elevation)) +    { +        elevation = F_APPROXIMATELY_ZERO; +    } + +    quat.setAngleAxis(-elevation, 0, 1, 0); +    LLQuaternion az_quat; +    az_quat.setAngleAxis(F_TWO_PI - azimuth, 0, 0, 1); +    quat *= az_quat; + +    getChild<LLVirtualTrackball>(FIELD_SKY_SUN_ROTATION)->setRotation(quat); + +    if (mLiveSky) +    { +        mLiveSky->setSunRotation(quat); +        mLiveSky->update(); +    }  }  void LLFloaterEnvironmentAdjust::onSunScaleChanged() @@ -341,10 +399,45 @@ void LLFloaterEnvironmentAdjust::onSunScaleChanged()  void LLFloaterEnvironmentAdjust::onMoonRotationChanged()  { -    if (!mLiveSky) -        return; -    mLiveSky->setMoonRotation(getChild<LLVirtualTrackball>(FIELD_SKY_MOON_ROTATION)->getRotation()); -    mLiveSky->update(); +    LLQuaternion quat = getChild<LLVirtualTrackball>(FIELD_SKY_MOON_ROTATION)->getRotation(); +    F32 azimuth; +    F32 elevation; +    LLVirtualTrackball::getAzimuthAndElevationDeg(quat, azimuth, elevation); +    getChild<LLUICtrl>(FIELD_SKY_MOON_AZIMUTH)->setValue(azimuth); +    getChild<LLUICtrl>(FIELD_SKY_MOON_ELEVATION)->setValue(elevation); +    if (mLiveSky) +    { +        mLiveSky->setMoonRotation(quat); +        mLiveSky->update(); +    } +} + +void LLFloaterEnvironmentAdjust::onMoonAzimElevChanged() +{ +    F32 azimuth = getChild<LLUICtrl>(FIELD_SKY_MOON_AZIMUTH)->getValue().asReal(); +    F32 elevation = getChild<LLUICtrl>(FIELD_SKY_MOON_ELEVATION)->getValue().asReal(); +    LLQuaternion quat; + +    azimuth *= DEG_TO_RAD; +    elevation *= DEG_TO_RAD; + +    if (is_approx_zero(elevation)) +    { +        elevation = F_APPROXIMATELY_ZERO; +    } + +    quat.setAngleAxis(-elevation, 0, 1, 0); +    LLQuaternion az_quat; +    az_quat.setAngleAxis(F_TWO_PI - azimuth, 0, 0, 1); +    quat *= az_quat; + +    getChild<LLVirtualTrackball>(FIELD_SKY_MOON_ROTATION)->setRotation(quat); + +    if (mLiveSky) +    { +        mLiveSky->setMoonRotation(quat); +        mLiveSky->update(); +    }  }  void LLFloaterEnvironmentAdjust::onCloudMapChanged() diff --git a/indra/newview/llfloaterenvironmentadjust.h b/indra/newview/llfloaterenvironmentadjust.h index cb38dbcfa8..05ff011be5 100644 --- a/indra/newview/llfloaterenvironmentadjust.h +++ b/indra/newview/llfloaterenvironmentadjust.h @@ -73,9 +73,11 @@ private:      void                        onGlowChanged();      void                        onStarBrightnessChanged();      void                        onSunRotationChanged(); +    void                        onSunAzimElevChanged();      void                        onSunScaleChanged();      void                        onMoonRotationChanged(); +    void                        onMoonAzimElevChanged();      void                        onCloudMapChanged();      void                        onWaterMapChanged(); diff --git a/indra/newview/llfloaterexperienceprofile.cpp b/indra/newview/llfloaterexperienceprofile.cpp index 2c9a8e64b7..a99a096ea7 100644 --- a/indra/newview/llfloaterexperienceprofile.cpp +++ b/indra/newview/llfloaterexperienceprofile.cpp @@ -211,6 +211,20 @@ bool LLFloaterExperienceProfile::experiencePermission( LLHandle<LLFloaterExperie      return false;  } +bool LLFloaterExperienceProfile::matchesKey(const LLSD& key) +{ +    if (key.has("experience_id")) +    { +        return mExperienceId == key["experience_id"].asUUID(); +    } +    else if (key.isUUID()) +    { +        return mExperienceId == key.asUUID(); +    } +    // Assume NULL uuid +    return mExperienceId.isNull(); +} +  void LLFloaterExperienceProfile::onClickEdit()  { diff --git a/indra/newview/llfloaterexperienceprofile.h b/indra/newview/llfloaterexperienceprofile.h index 1394418d91..f9b6e2e2eb 100644 --- a/indra/newview/llfloaterexperienceprofile.h +++ b/indra/newview/llfloaterexperienceprofile.h @@ -51,6 +51,8 @@ public:      LLFloaterExperienceProfile(const LLSD& data);      virtual ~LLFloaterExperienceProfile(); +     +    /* virtual */ bool matchesKey(const LLSD& key);      LLUUID getExperienceId() const { return mExperienceId; }      void setPreferences( const LLSD& content ); diff --git a/indra/newview/llfloaterfixedenvironment.cpp b/indra/newview/llfloaterfixedenvironment.cpp index 41bbd5e8f9..4f2c36f45b 100644 --- a/indra/newview/llfloaterfixedenvironment.cpp +++ b/indra/newview/llfloaterfixedenvironment.cpp @@ -128,7 +128,7 @@ void LLFloaterFixedEnvironment::onOpen(const LLSD& key)      updateEditEnvironment();      syncronizeTabs();      refresh(); -    LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_EDIT, LLEnvironment::TRANSITION_FAST); +    LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_EDIT, LLEnvironment::TRANSITION_INSTANT);  } @@ -180,7 +180,7 @@ void LLFloaterFixedEnvironment::setEditSettingsAndUpdate(const LLSettingsBase::p      updateEditEnvironment();      syncronizeTabs();      refresh(); -    LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_FAST); +    LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_INSTANT);  }  void LLFloaterFixedEnvironment::syncronizeTabs() @@ -460,7 +460,7 @@ void LLFloaterFixedEnvironmentWater::loadWaterSettingFromFile(const std::vector<      setDirtyFlag();      LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_EDIT, legacywater);      setEditSettings(legacywater); -    LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_FAST, true); +    LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_INSTANT, true);  }  //========================================================================= @@ -548,7 +548,7 @@ void LLFloaterFixedEnvironmentSky::loadSkySettingFromFile(const std::vector<std:      setDirtyFlag();      LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_EDIT, legacysky);      setEditSettings(legacysky); -    LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_FAST, true); +    LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_INSTANT, true);  }  //========================================================================= diff --git a/indra/newview/llfloatergridstatus.cpp b/indra/newview/llfloatergridstatus.cpp index faa7e9f3db..9745e17bbb 100644 --- a/indra/newview/llfloatergridstatus.cpp +++ b/indra/newview/llfloatergridstatus.cpp @@ -95,6 +95,7 @@ void LLFloaterGridStatus::getGridStatusRSSCoro()      LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);      LLCore::HttpHeaders::ptr_t httpHeaders(new LLCore::HttpHeaders); +    httpOpts->setSSLVerifyPeer(false); // We want this data even if SSL fails      httpHeaders->append(HTTP_OUT_HEADER_CONTENT_TYPE, HTTP_CONTENT_TEXT_XML);      std::string url = gSavedSettings.getString("GridStatusRSS"); diff --git a/indra/newview/llfloaterhandler.cpp b/indra/newview/llfloaterhandler.cpp index e2160498e9..8ebb14149c 100644 --- a/indra/newview/llfloaterhandler.cpp +++ b/indra/newview/llfloaterhandler.cpp @@ -26,6 +26,7 @@  #include "llfloater.h"  #include "llmediactrl.h" +#include "llfloaterreg.h"  // register with dispatch via global object  LLFloaterHandler gFloaterHandler; @@ -50,9 +51,15 @@ LLFloater* get_parent_floater(LLView* view)  bool LLFloaterHandler::handle(const LLSD ¶ms, const LLSD &query_map, LLMediaCtrl *web)  { -	if (params.size() < 2) return false; +	if (params.size() < 1) return false;  	LLFloater* floater = NULL;  	// *TODO: implement floater lookup by name + +	if (params[0].asString() == "destinations") +	{ +		LLFloaterReg::toggleInstanceOrBringToFront("destinations"); +		return true; +	}  	if (params[0].asString() == "self")  	{  		if (web) diff --git a/indra/newview/llfloaterhowto.cpp b/indra/newview/llfloaterhowto.cpp new file mode 100644 index 0000000000..a359fb7c7d --- /dev/null +++ b/indra/newview/llfloaterhowto.cpp @@ -0,0 +1,92 @@ +/**  + * @file llfloaterhowto.cpp + * @brief A variant of web floater meant to open guidebook + * + * $LicenseInfo:firstyear=2021&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2021, 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 "llfloaterhowto.h" + +#include "llfloaterreg.h" +#include "llviewercontrol.h" +#include "llweb.h" + + +const S32 STACK_WIDTH = 300; +const S32 STACK_HEIGHT = 505; // content will be 500 + +LLFloaterHowTo::LLFloaterHowTo(const Params& key) : +    LLFloaterWebContent(key) +{ +    mShowPageTitle = false; +} + +BOOL LLFloaterHowTo::postBuild() +{ +    LLFloaterWebContent::postBuild(); + +    return TRUE; +} + +void LLFloaterHowTo::onOpen(const LLSD& key) +{ +    LLFloaterWebContent::Params p(key); +    if (!p.url.isProvided() || p.url.getValue().empty()) +    { +        std::string url = gSavedSettings.getString("GuidebookURL"); +        p.url = LLWeb::expandURLSubstitutions(url, LLSD()); +    } +    p.show_chrome = false; + +    LLFloaterWebContent::onOpen(p); + +    if (p.preferred_media_size().isEmpty()) +    { +        // Elements from LLFloaterWebContent did not pick up restored size (save_rect) of LLFloaterHowTo +        // set the stack size and position (alternative to preferred_media_size) +        LLLayoutStack *stack = getChild<LLLayoutStack>("stack1"); +        LLRect stack_rect = stack->getRect(); +        stack->reshape(STACK_WIDTH, STACK_HEIGHT); +        stack->setOrigin(stack_rect.mLeft, stack_rect.mTop - STACK_HEIGHT); +        stack->updateLayout(); +    } +} + +LLFloaterHowTo* LLFloaterHowTo::getInstance() +{ +    return LLFloaterReg::getTypedInstance<LLFloaterHowTo>("guidebook"); +} + +BOOL LLFloaterHowTo::handleKeyHere(KEY key, MASK mask) +{ +	BOOL handled = FALSE; + +	if (KEY_F1 == key ) +	{ +		closeFloater(); +		handled = TRUE; +	} + +	return handled; +} diff --git a/indra/newview/llfloaterhowto.h b/indra/newview/llfloaterhowto.h new file mode 100644 index 0000000000..d8da355600 --- /dev/null +++ b/indra/newview/llfloaterhowto.h @@ -0,0 +1,58 @@ +/**  + * @file llfloaterhowto.h + * @brief A variant of web floater meant to open guidebook + * + * $LicenseInfo:firstyear=2021&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2021, 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_LLFLOATERHOWTO_H +#define LL_LLFLOATERHOWTO_H + +#include "llfloaterwebcontent.h" + +class LLMediaCtrl; + + +class LLFloaterHowTo : +    public LLFloaterWebContent +{ +public: +    LOG_CLASS(LLFloaterHowTo); + +    typedef LLFloaterWebContent::Params Params; + +    LLFloaterHowTo(const Params& key); + +    void onOpen(const LLSD& key) override; + +    BOOL handleKeyHere(KEY key, MASK mask) override; + +    static LLFloaterHowTo* getInstance(); + +    bool matchesKey(const LLSD& key) override { return true; /*single instance*/ }; + +private: +    BOOL postBuild() override; +}; + +#endif  // LL_LLFLOATERHOWTO_H + diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp index a6531ed7e1..3a850d4b68 100644 --- a/indra/newview/llfloaterimnearbychat.cpp +++ b/indra/newview/llfloaterimnearbychat.cpp @@ -67,6 +67,7 @@  #include "llviewerchat.h"  #include "lltranslate.h"  #include "llautoreplace.h" +#include "lluiusage.h"  S32 LLFloaterIMNearbyChat::sLastSpecialChatChannel = 0; @@ -697,6 +698,7 @@ void LLFloaterIMNearbyChat::sendChatFromViewer(const std::string &utf8text, ECha  void LLFloaterIMNearbyChat::sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL animate)  { +	LLUIUsage::instance().logCommand("Chat.Send"); // pseuo-command  	// Look for "/20 foo" channel chats.  	S32 channel = 0;  	LLWString out_text = stripChannelNumber(wtext, &channel); diff --git a/indra/newview/llfloaterlandholdings.cpp b/indra/newview/llfloaterlandholdings.cpp index f34760a6bf..749a3d2686 100644 --- a/indra/newview/llfloaterlandholdings.cpp +++ b/indra/newview/llfloaterlandholdings.cpp @@ -51,6 +51,9 @@  #include "llgroupactions.h" +const std::string LINDEN_HOMES_SKU = "131"; +bool LLFloaterLandHoldings::sHasLindenHome = false; +  // protected  LLFloaterLandHoldings::LLFloaterLandHoldings(const LLSD& key)  :	LLFloater(key), @@ -148,10 +151,24 @@ void LLFloaterLandHoldings::refresh()  void LLFloaterLandHoldings::processPlacesReply(LLMessageSystem* msg, void**)  {  	LLFloaterLandHoldings* self = LLFloaterReg::findTypedInstance<LLFloaterLandHoldings>("land_holdings"); - -	// Is this packet from an old, closed window? +	S32 count = msg->getNumberOfBlocks("QueryData"); +	std::string land_sku; +	sHasLindenHome = false;  	if (!self)  	{ +		for (S32 i = 0; i < count; i++) +		{ +			if ( msg->getSizeFast(_PREHASH_QueryData, i, _PREHASH_ProductSKU) > 0 ) +			{ +				msg->getStringFast(	_PREHASH_QueryData, _PREHASH_ProductSKU, land_sku, i); + +				if (LINDEN_HOMES_SKU == land_sku) +				{ +					sHasLindenHome = true; +					return; +				} +			} +		}  		return;  	} @@ -174,12 +191,9 @@ void LLFloaterLandHoldings::processPlacesReply(LLMessageSystem* msg, void**)  	F32		global_x;  	F32		global_y;  	std::string	sim_name; -	std::string land_sku;  	std::string land_type; -	S32 i; -	S32 count = msg->getNumberOfBlocks("QueryData"); -	for (i = 0; i < count; i++) +	for (S32 i = 0; i < count; i++)  	{  		msg->getUUID("QueryData", "OwnerID", owner_id, i);  		msg->getString("QueryData", "Name", name, i); @@ -196,6 +210,10 @@ void LLFloaterLandHoldings::processPlacesReply(LLMessageSystem* msg, void**)  			msg->getStringFast(	_PREHASH_QueryData, _PREHASH_ProductSKU, land_sku, i);  			LL_INFOS() << "Land sku: " << land_sku << LL_ENDL;  			land_type = LLProductInfoRequestManager::instance().getDescriptionForSku(land_sku); +			if (LINDEN_HOMES_SKU == land_sku) +			{ +				sHasLindenHome = true; +			}  		}  		else  		{ diff --git a/indra/newview/llfloaterlandholdings.h b/indra/newview/llfloaterlandholdings.h index d1d510bb40..90e75b1062 100644 --- a/indra/newview/llfloaterlandholdings.h +++ b/indra/newview/llfloaterlandholdings.h @@ -57,6 +57,8 @@ public:  	static void onGrantList(void* data); +	static bool sHasLindenHome; +  protected:  	void refreshAggregates(); diff --git a/indra/newview/llfloaterurlentry.cpp b/indra/newview/llfloaterurlentry.cpp index f2efef0c33..63bce3d2eb 100644 --- a/indra/newview/llfloaterurlentry.cpp +++ b/indra/newview/llfloaterurlentry.cpp @@ -122,8 +122,7 @@ void LLFloaterURLEntry::headerFetchComplete(S32 status, const std::string& mime_  		}  	} -	// Decrement the cursor -	getWindow()->decBusyCount(); +  	getChildView("loading_label")->setVisible( false);  	closeFloater();  } @@ -302,3 +301,9 @@ bool LLFloaterURLEntry::callback_clear_url_list(const LLSD& notification, const  	}  	return false;  } + +void LLFloaterURLEntry::onClose( bool app_quitting ) +{ +    // Decrement the cursor +    getWindow()->decBusyCount(); +} diff --git a/indra/newview/llfloaterurlentry.h b/indra/newview/llfloaterurlentry.h index 20f4604907..04a8eca069 100644 --- a/indra/newview/llfloaterurlentry.h +++ b/indra/newview/llfloaterurlentry.h @@ -42,6 +42,7 @@ public:  	// that panel via the handle.  	static LLHandle<LLFloater> show(LLHandle<LLPanel> panel_land_media_handle, const std::string media_url);  	/*virtual*/	BOOL	postBuild(); +    /*virtual*/ void onClose( bool app_quitting );  	void headerFetchComplete(S32 status, const std::string& mime_type);  	bool addURLToCombobox(const std::string& media_url); diff --git a/indra/newview/llfolderviewmodelinventory.h b/indra/newview/llfolderviewmodelinventory.h index 06a908cccc..51b98339c4 100644 --- a/indra/newview/llfolderviewmodelinventory.h +++ b/indra/newview/llfolderviewmodelinventory.h @@ -45,6 +45,7 @@ public:  	virtual LLFolderType::EType getPreferredType() const = 0;  	virtual void showProperties(void) = 0;  	virtual BOOL isItemInTrash( void) const { return FALSE; } // TODO: make   into pure virtual. +	virtual BOOL isAgentInventory() const { return FALSE; }  	virtual BOOL isUpToDate() const = 0;  	virtual bool hasChildren() const = 0;  	virtual LLInventoryType::EType getInventoryType() const = 0; diff --git a/indra/newview/llhudnametag.cpp b/indra/newview/llhudnametag.cpp index 4ed802138d..9d49c30a49 100644 --- a/indra/newview/llhudnametag.cpp +++ b/indra/newview/llhudnametag.cpp @@ -105,6 +105,9 @@ LLHUDNameTag::LLHUDNameTag(const U8 type)  {  	LLPointer<LLHUDNameTag> ptr(this);  	sTextObjects.insert(ptr); + +    mRoundedRectImgp = LLUI::getUIImage("Rounded_Rect"); +    mRoundedRectTopImgp = LLUI::getUIImage("Rounded_Rect_Top");  }  LLHUDNameTag::~LLHUDNameTag() @@ -274,9 +277,6 @@ void LLHUDNameTag::renderText(BOOL for_select)  	mOffsetY = lltrunc(mHeight * ((mVertAlignment == ALIGN_VERT_CENTER) ? 0.5f : 1.f)); -	// *TODO: cache this image -	LLUIImagePtr imagep = LLUI::getUIImage("Rounded_Rect"); -  	// *TODO: make this a per-text setting  	LLColor4 bg_color = LLUIColorTable::instance().getColor("NameTagBackground");  	bg_color.setAlpha(gSavedSettings.getF32("ChatBubbleOpacity") * alpha_factor); @@ -306,17 +306,16 @@ void LLHUDNameTag::renderText(BOOL for_select)  	LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);  	LLRect screen_rect;  	screen_rect.setCenterAndSize(0, static_cast<S32>(lltrunc(-mHeight / 2 + mOffsetY)), static_cast<S32>(lltrunc(mWidth)), static_cast<S32>(lltrunc(mHeight))); -	imagep->draw3D(render_position, x_pixel_vec, y_pixel_vec, screen_rect, bg_color); +    mRoundedRectImgp->draw3D(render_position, x_pixel_vec, y_pixel_vec, screen_rect, bg_color);  	if (mLabelSegments.size())  	{ -		LLUIImagePtr rect_top_image = LLUI::getUIImage("Rounded_Rect_Top");  		LLRect label_top_rect = screen_rect;  		const S32 label_height = ll_round((mFontp->getLineHeight() * (F32)mLabelSegments.size() + (VERTICAL_PADDING / 3.f)));  		label_top_rect.mBottom = label_top_rect.mTop - label_height;  		LLColor4 label_top_color = text_color;  		label_top_color.mV[VALPHA] = gSavedSettings.getF32("ChatBubbleOpacity") * alpha_factor; -		rect_top_image->draw3D(render_position, x_pixel_vec, y_pixel_vec, label_top_rect, label_top_color); +        mRoundedRectTopImgp->draw3D(render_position, x_pixel_vec, y_pixel_vec, label_top_rect, label_top_color);  	}  	F32 y_offset = (F32)mOffsetY; diff --git a/indra/newview/llhudnametag.h b/indra/newview/llhudnametag.h index 20272a8232..7577dd5de6 100644 --- a/indra/newview/llhudnametag.h +++ b/indra/newview/llhudnametag.h @@ -40,8 +40,8 @@  #include <set>  #include <vector> -class LLDrawable;  class LLHUDNameTag; +class LLUIImage;  struct llhudnametag_further_away  { @@ -171,6 +171,8 @@ private:  	EVertAlignment	mVertAlignment;  	S32				mLOD;  	BOOL			mHidden; +	LLPointer<LLUIImage> mRoundedRectImgp; +	LLPointer<LLUIImage> mRoundedRectTopImgp;  	static BOOL    sDisplayText ;  	static std::set<LLPointer<LLHUDNameTag> > sTextObjects; diff --git a/indra/newview/llhudtext.cpp b/indra/newview/llhudtext.cpp index 72d28a3d44..7c957ac712 100644 --- a/indra/newview/llhudtext.cpp +++ b/indra/newview/llhudtext.cpp @@ -138,9 +138,6 @@ void LLHUDText::renderText()  	mOffsetY = lltrunc(mHeight * ((mVertAlignment == ALIGN_VERT_CENTER) ? 0.5f : 1.f)); -	// *TODO: cache this image -	LLUIImagePtr imagep = LLUI::getUIImage("Rounded_Square"); -  	// *TODO: make this a per-text setting  	LLColor4 bg_color = LLUIColorTable::instance().getColor("ObjectBubbleColor");  	bg_color.setAlpha(gSavedSettings.getF32("ChatBubbleOpacity") * alpha_factor); diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index d35d8456be..fc8179f3b4 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -1835,28 +1835,11 @@ void LLItemBridge::restoreToWorld()  void LLItemBridge::gotoItem()  { -	LLInventoryObject *obj = getInventoryObject(); -	if (obj && obj->getIsLinkType()) -	{ -		const LLUUID inbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX); -		if (gInventory.isObjectDescendentOf(obj->getLinkedUUID(), inbox_id)) -		{ -			LLSidepanelInventory *sidepanel_inventory = LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory"); -			if (sidepanel_inventory && sidepanel_inventory->getInboxPanel()) -			{ -				sidepanel_inventory->getInboxPanel()->setSelection(obj->getLinkedUUID(), TAKE_FOCUS_NO); -			} -		} -		else -		{ -			LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel(); -			if (active_panel) -			{ -				active_panel->setSelection(obj->getLinkedUUID(), TAKE_FOCUS_NO); -			} -		} - -	} +    LLInventoryObject *obj = getInventoryObject(); +    if (obj && obj->getIsLinkType()) +    { +        show_item_original(obj->getUUID()); +    }  }  LLUIImagePtr LLItemBridge::getIcon() const @@ -3987,6 +3970,12 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t&   items  	const LLUUID &lost_and_found_id = model->findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND);  	const LLUUID &favorites = model->findCategoryUUIDForType(LLFolderType::FT_FAVORITE);  	const LLUUID &marketplace_listings_id = model->findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false); +	const LLUUID &outfits_id = model->findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS, false); + +	if (outfits_id == mUUID) +	{ +		items.push_back(std::string("New Outfit")); +	}  	if (lost_and_found_id == mUUID)  	{ @@ -4085,7 +4074,8 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t&   items  		// Not sure what the right thing is to do here.  		if (!isCOFFolder() && cat && (cat->getPreferredType() != LLFolderType::FT_OUTFIT))  		{ -			if (!isInboxFolder()) // don't allow creation in inbox +			if (!isInboxFolder() // don't allow creation in inbox +				&& outfits_id != mUUID)  			{  				// Do not allow to create 2-level subfolder in the Calling Card/Friends folder. EXT-694.  				if (!LLFriendCardsManager::instance().isCategoryInFriendFolder(cat)) @@ -4101,6 +4091,12 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t&   items                      items.push_back(std::string("New Body Parts"));                      items.push_back(std::string("New Settings"));                      items.push_back(std::string("upload_def")); + +                    if (!LLEnvironment::instance().isInventoryEnabled()) +                    { +                        disabled_items.push_back("New Settings"); +                    } +                  }  			}  			getClipboardEntries(false, items, disabled_items, flags); @@ -7037,8 +7033,8 @@ void LLSettingsBridge::performAction(LLInventoryModel* model, std::string action          if (!item)               return;          LLUUID asset_id = item->getAssetUUID(); -        LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, asset_id); -        LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL); +        LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, asset_id, LLEnvironment::TRANSITION_INSTANT); +        LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::TRANSITION_INSTANT);      }      else if ("apply_settings_parcel" == action)      { @@ -7212,21 +7208,17 @@ void LLLinkFolderBridge::performAction(LLInventoryModel* model, std::string acti  }  void LLLinkFolderBridge::gotoItem()  { -	const LLUUID &cat_uuid = getFolderID(); -	if (!cat_uuid.isNull()) -	{ -		LLFolderViewItem *base_folder = mInventoryPanel.get()->getItemByID(cat_uuid); -		if (base_folder) -		{ -			if (LLInventoryModel* model = getInventoryModel()) -			{ -				model->fetchDescendentsOf(cat_uuid); -			} -			base_folder->setOpen(TRUE); -			mRoot->setSelection(base_folder,TRUE); -			mRoot->scrollToShowSelection(); -		} -	} +    LLItemBridge::gotoItem(); + +    const LLUUID &cat_uuid = getFolderID(); +    if (!cat_uuid.isNull()) +    { +        LLFolderViewItem *base_folder = LLInventoryPanel::getActiveInventoryPanel()->getItemByID(cat_uuid); +        if (base_folder) +        { +            base_folder->setOpen(TRUE); +        } +    }  }  const LLUUID &LLLinkFolderBridge::getFolderID() const  { diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp index 2a22eb1329..411311bbea 100644 --- a/indra/newview/llinventoryfilter.cpp +++ b/indra/newview/llinventoryfilter.cpp @@ -63,7 +63,8 @@ LLInventoryFilter::FilterOps::FilterOps(const Params& p)  	mPermissions(p.permissions),  	mFilterTypes(p.types),  	mFilterUUID(p.uuid), -	mFilterLinks(p.links) +	mFilterLinks(p.links), +	mSearchVisibility(p.search_visibility)  {  } @@ -155,6 +156,7 @@ bool LLInventoryFilter::check(const LLFolderViewModelItem* item)  	passed = passed && checkAgainstPermissions(listener);  	passed = passed && checkAgainstFilterLinks(listener);  	passed = passed && checkAgainstCreator(listener); +	passed = passed && checkAgainstSearchVisibility(listener);  	return passed;  } @@ -583,6 +585,27 @@ bool LLInventoryFilter::checkAgainstCreator(const LLFolderViewModelItemInventory  	}  } +bool LLInventoryFilter::checkAgainstSearchVisibility(const LLFolderViewModelItemInventory* listener) const +{ +	if (!listener || !hasFilterString()) return TRUE; + +	const LLUUID object_id = listener->getUUID(); +	const LLInventoryObject *object = gInventory.getObject(object_id); +	if (!object) return TRUE; + +	const BOOL is_link = object->getIsLinkType(); +	if (is_link && ((mFilterOps.mSearchVisibility & VISIBILITY_LINKS) == 0)) +		return FALSE; + +	if (listener->isItemInTrash() && ((mFilterOps.mSearchVisibility & VISIBILITY_TRASH) == 0)) +		return FALSE; + +	if (!listener->isAgentInventory() && ((mFilterOps.mSearchVisibility & VISIBILITY_LIBRARY) == 0)) +		return FALSE; + +	return TRUE; +} +  const std::string& LLInventoryFilter::getFilterSubString(BOOL trim) const  {  	return mFilterSubString; @@ -751,6 +774,61 @@ void LLInventoryFilter::setFilterMarketplaceListingFolders(bool select_only_list      }  } + +void LLInventoryFilter::toggleSearchVisibilityLinks() +{ +	bool hide_links = mFilterOps.mSearchVisibility & VISIBILITY_LINKS; +	if (hide_links) +	{ +		mFilterOps.mSearchVisibility &= ~VISIBILITY_LINKS; +	} +	else +	{ +		mFilterOps.mSearchVisibility |= VISIBILITY_LINKS; +	} + +	if (hasFilterString()) +	{ +		setModified(hide_links ? FILTER_MORE_RESTRICTIVE : FILTER_LESS_RESTRICTIVE); +	} +} + +void LLInventoryFilter::toggleSearchVisibilityTrash() +{ +	bool hide_trash = mFilterOps.mSearchVisibility & VISIBILITY_TRASH; +	if (hide_trash) +	{ +		mFilterOps.mSearchVisibility &= ~VISIBILITY_TRASH; +	} +	else +	{ +		mFilterOps.mSearchVisibility |= VISIBILITY_TRASH; +	} + +	if (hasFilterString()) +	{ +		setModified(hide_trash ? FILTER_MORE_RESTRICTIVE : FILTER_LESS_RESTRICTIVE); +	} +} + +void LLInventoryFilter::toggleSearchVisibilityLibrary() +{ +	bool hide_library = mFilterOps.mSearchVisibility & VISIBILITY_LIBRARY; +	if (hide_library) +	{ +		mFilterOps.mSearchVisibility &= ~VISIBILITY_LIBRARY; +	} +	else +	{ +		mFilterOps.mSearchVisibility |= VISIBILITY_LIBRARY; +	} + +	if (hasFilterString()) +	{ +		setModified(hide_library ? FILTER_MORE_RESTRICTIVE : FILTER_LESS_RESTRICTIVE); +	} +} +  void LLInventoryFilter::setFilterNoMarketplaceFolder()  {      mFilterOps.mFilterTypes |= FILTERTYPE_NO_MARKETPLACE_ITEMS; @@ -862,6 +940,44 @@ void LLInventoryFilter::setFilterSubString(const std::string& string)  	}  } +void LLInventoryFilter::setSearchVisibilityTypes(U32 types) +{ +	if (mFilterOps.mSearchVisibility != types) +	{ +		// keep current items only if no perm bits getting turned off +		BOOL fewer_bits_set = (mFilterOps.mSearchVisibility & ~types); +		BOOL more_bits_set = (~mFilterOps.mSearchVisibility & types); +		mFilterOps.mSearchVisibility = types; + +		if (more_bits_set && fewer_bits_set) +		{ +			setModified(FILTER_RESTART); +		} +		else if (more_bits_set) +		{ +			// target must have all requested permission bits, so more bits == more restrictive +			setModified(FILTER_MORE_RESTRICTIVE); +		} +		else if (fewer_bits_set) +		{ +			setModified(FILTER_LESS_RESTRICTIVE); +		} +	} +} + +void LLInventoryFilter::setSearchVisibilityTypes(const Params& params) +{ +	if (!params.validateBlock()) +	{ +		return; +	} + +	if (params.filter_ops.search_visibility.isProvided()) +	{ +		setSearchVisibilityTypes(params.filter_ops.search_visibility); +	} +} +  void LLInventoryFilter::setFilterPermissions(PermissionMask perms)  {  	if (mFilterOps.mPermissions != perms) @@ -1263,6 +1379,18 @@ const std::string& LLInventoryFilter::getFilterText()  		filtered_by_all_types = FALSE;  	} +	if (isFilterObjectTypesWith(LLInventoryType::IT_SETTINGS)) +	{ +		filtered_types +=  LLTrans::getString("Settings"); +		filtered_by_type = TRUE; +		num_filter_types++; +	} +	else +	{ +		not_filtered_types +=  LLTrans::getString("Settings"); +		filtered_by_all_types = FALSE; +	} +  	if (!LLInventoryModelBackgroundFetch::instance().folderFetchActive()  		&& filtered_by_type  		&& !filtered_by_all_types) @@ -1318,6 +1446,7 @@ void LLInventoryFilter::toParams(Params& params) const  	params.filter_ops.show_folder_state = getShowFolderState();  	params.filter_ops.creator_type = getFilterCreatorType();  	params.filter_ops.permissions = getFilterPermissions(); +	params.filter_ops.search_visibility = getSearchVisibilityTypes();  	params.substring = getFilterSubString();  	params.since_logoff = isSinceLogoff();  } @@ -1341,6 +1470,7 @@ void LLInventoryFilter::fromParams(const Params& params)  	setShowFolderState(params.filter_ops.show_folder_state);  	setFilterCreator(params.filter_ops.creator_type);  	setFilterPermissions(params.filter_ops.permissions); +	setSearchVisibilityTypes(params.filter_ops.search_visibility);  	setFilterSubString(params.substring);  	setDateRangeLastLogoff(params.since_logoff);  } @@ -1370,6 +1500,11 @@ U64 LLInventoryFilter::getFilterSettingsTypes() const      return mFilterOps.mFilterSettingsTypes;  } +U64 LLInventoryFilter::getSearchVisibilityTypes() const +{ +	return mFilterOps.mSearchVisibility; +} +  bool LLInventoryFilter::hasFilterString() const  {  	return mFilterSubString.size() > 0; diff --git a/indra/newview/llinventoryfilter.h b/indra/newview/llinventoryfilter.h index 61cc5ae602..384de3e889 100644 --- a/indra/newview/llinventoryfilter.h +++ b/indra/newview/llinventoryfilter.h @@ -99,6 +99,14 @@ public:  		FILTERCREATOR_OTHERS  	}; +	enum ESearchVisibility +	{ +		VISIBILITY_NONE = 0, +		VISIBILITY_TRASH = 0x1 << 0, +		VISIBILITY_LIBRARY = 0x1 << 1, +		VISIBILITY_LINKS	= 0x1 << 2 +	}; +  	struct FilterOps  	{  		struct DateRange : public LLInitParam::Block<DateRange> @@ -116,11 +124,13 @@ public:  		struct Params : public LLInitParam::Block<Params>  		{ -			Optional<U32>				types; +			Optional<U32>				types, +										search_visibility;  			Optional<U64>				object_types,  										wearable_types,                                          settings_types,  										category_types; +										  			Optional<EFilterLink>		links;  			Optional<LLUUID>			uuid;  			Optional<DateRange>			date_range; @@ -137,6 +147,7 @@ public:                  settings_types("settings_types", 0xffffFFFFffffFFFFULL),  				category_types("category_types", 0xffffFFFFffffFFFFULL),  				links("links", FILTERLINK_INCLUDE_LINKS), +				search_visibility("search_visibility", 0xFFFFFFFF),  				uuid("uuid"),  				date_range("date_range"),  				hours_ago("hours_ago", 0), @@ -149,7 +160,8 @@ public:  		FilterOps(const Params& = Params()); -		U32 			mFilterTypes; +		U32 			mFilterTypes, +						mSearchVisibility;  		U64				mFilterObjectTypes,   // For _OBJECT  						mFilterWearableTypes,                          mFilterSettingsTypes, // for _SETTINGS @@ -193,7 +205,8 @@ public:  	U64 				getFilterObjectTypes() const;  	U64					getFilterCategoryTypes() const;  	U64					getFilterWearableTypes() const; -    U64                 getFilterSettingsTypes() const; +	U64					getFilterSettingsTypes() const; +	U64					getSearchVisibilityTypes() const;  	bool 				isFilterObjectTypesWith(LLInventoryType::EType t) const;  	void 				setFilterObjectTypes(U64 types); @@ -213,6 +226,12 @@ public:  	ESearchType			getSearchType() { return mSearchType; }  	void 				setFilterCreator(EFilterCreatorType type); +	void				toggleSearchVisibilityLinks(); +	void				toggleSearchVisibilityTrash(); +	void				toggleSearchVisibilityLibrary(); +	void 				setSearchVisibilityTypes(U32 types); +	void 				setSearchVisibilityTypes(const Params& params); +  	void 				setFilterSubString(const std::string& string);  	const std::string& 	getFilterSubString(BOOL trim = FALSE) const;  	const std::string& 	getFilterSubStringOrig() const { return mFilterSubStringOrig; }  @@ -310,6 +329,7 @@ private:  	bool 				checkAgainstPermissions(const LLInventoryItem* item) const;  	bool 				checkAgainstFilterLinks(const class LLFolderViewModelItemInventory* listener) const;  	bool 				checkAgainstCreator(const class LLFolderViewModelItemInventory* listener) const; +	bool				checkAgainstSearchVisibility(const class LLFolderViewModelItemInventory* listener) const;  	bool				checkAgainstClipboard(const LLUUID& object_id) const;  	FilterOps				mFilterOps; diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 7a0ea8b668..f2e06d19f3 100644 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -774,40 +774,45 @@ void show_item_profile(const LLUUID& item_uuid)  void show_item_original(const LLUUID& item_uuid)  { -	LLFloater* floater_inventory = LLFloaterReg::getInstance("inventory"); -	if (!floater_inventory) -	{ -		LL_WARNS() << "Could not find My Inventory floater" << LL_ENDL; -		return; -	} - -	//sidetray inventory panel -	LLSidepanelInventory *sidepanel_inventory =	LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory"); - -	bool do_reset_inventory_filter = !floater_inventory->isInVisibleChain(); +    LLFloater* floater_inventory = LLFloaterReg::getInstance("inventory"); +    if (!floater_inventory) +    { +        LL_WARNS() << "Could not find My Inventory floater" << LL_ENDL; +        return; +    } +    LLSidepanelInventory *sidepanel_inventory =	LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory"); +    if (sidepanel_inventory) +    { +        LLPanelMainInventory* main_inventory = sidepanel_inventory->getMainInventoryPanel(); +        if (main_inventory) +        { +            main_inventory->resetFilters(); +        } +        reset_inventory_filter(); -	LLInventoryPanel* active_panel = LLInventoryPanel::getActiveInventoryPanel(); -	if (!active_panel)  -	{ -		//this may happen when there is no floatera and other panel is active in inventory tab +        if (!LLFloaterReg::getTypedInstance<LLFloaterSidePanelContainer>("inventory")->isInVisibleChain()) +        { +            LLFloaterReg::toggleInstanceOrBringToFront("inventory"); +        } -		if	(sidepanel_inventory) -		{ -			sidepanel_inventory->showInventoryPanel(); -		} -	} -	 -	active_panel = LLInventoryPanel::getActiveInventoryPanel(); -	if (!active_panel)  -	{ -		return; -	} -	active_panel->setSelection(gInventory.getLinkedItemID(item_uuid), TAKE_FOCUS_YES); -	 -	if(do_reset_inventory_filter) -	{ -		reset_inventory_filter(); -	} +        const LLUUID inbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX); +        if (gInventory.isObjectDescendentOf(gInventory.getLinkedItemID(item_uuid), inbox_id)) +        { +            if (sidepanel_inventory->getInboxPanel()) +            { +                sidepanel_inventory->openInbox(); +                sidepanel_inventory->getInboxPanel()->setSelection(gInventory.getLinkedItemID(item_uuid), TAKE_FOCUS_YES); +            } +        } +        else +        { +            sidepanel_inventory->selectAllItemsPanel(); +            if (sidepanel_inventory->getActivePanel()) +            { +                sidepanel_inventory->getActivePanel()->setSelection(gInventory.getLinkedItemID(item_uuid), TAKE_FOCUS_YES); +            } +        } +    }  } @@ -1842,6 +1847,26 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_      return result && !has_bad_items;  } +void change_item_parent(const LLUUID& item_id, const LLUUID& new_parent_id) +{ +	LLInventoryItem* inv_item = gInventory.getItem(item_id); +	if (inv_item) +	{ +		LLInventoryModel::update_list_t update; +		LLInventoryModel::LLCategoryUpdate old_folder(inv_item->getParentUUID(), -1); +		update.push_back(old_folder); +		LLInventoryModel::LLCategoryUpdate new_folder(new_parent_id, 1); +		update.push_back(new_folder); +		gInventory.accountForUpdate(update); + +		LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(inv_item); +		new_item->setParent(new_parent_id); +		new_item->updateParentOnServer(FALSE); +		gInventory.updateItem(new_item); +		gInventory.notifyObservers(); +	} +} +  ///----------------------------------------------------------------------------  /// LLInventoryCollectFunctor implementations  ///---------------------------------------------------------------------------- diff --git a/indra/newview/llinventoryfunctions.h b/indra/newview/llinventoryfunctions.h index 04eb962372..37c3c47336 100644 --- a/indra/newview/llinventoryfunctions.h +++ b/indra/newview/llinventoryfunctions.h @@ -92,6 +92,8 @@ S32  depth_nesting_in_marketplace(LLUUID cur_uuid);  LLUUID nested_parent_id(LLUUID cur_uuid, S32 depth);  S32 compute_stock_count(LLUUID cat_uuid, bool force_count = false); +void change_item_parent(const LLUUID& item_id, const LLUUID& new_parent_id); +  /**                    Miscellaneous global functions   **                                                                            **   *******************************************************************************/ diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp index 74d9e895c2..3608f9e23f 100644 --- a/indra/newview/llinventorypanel.cpp +++ b/indra/newview/llinventorypanel.cpp @@ -158,7 +158,8 @@ LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p) :  	mViewsInitialized(VIEWS_UNINITIALIZED),  	mInvFVBridgeBuilder(NULL),  	mInventoryViewModel(p.name), -	mGroupedItemBridge(new LLFolderViewGroupedItemBridge) +	mGroupedItemBridge(new LLFolderViewGroupedItemBridge), +	mFocusSelection(false)  {  	mInvFVBridgeBuilder = &INVENTORY_BRIDGE_BUILDER; @@ -1240,6 +1241,7 @@ void LLInventoryPanel::setSelectCallback(const boost::function<void (const std::  void LLInventoryPanel::clearSelection()  {  	mSelectThisID.setNull(); +	mFocusSelection = false;  }  LLInventoryPanel::selected_items_t LLInventoryPanel::getSelectedItems() const @@ -1714,15 +1716,17 @@ LLFolderViewFolder* LLInventoryPanel::getFolderByID(const LLUUID& id)  void LLInventoryPanel::setSelectionByID( const LLUUID& obj_id, BOOL    take_keyboard_focus )  {  	LLFolderViewItem* itemp = getItemByID(obj_id); -	if(itemp && itemp->getViewModelItem()) +	if(itemp && itemp->getViewModelItem() && itemp->passedFilter())  	{  		itemp->arrangeAndSet(TRUE, take_keyboard_focus);  		mSelectThisID.setNull(); +		mFocusSelection = false;  		return;  	}  	else  	{  		// save the desired item to be selected later (if/when ready) +		mFocusSelection = take_keyboard_focus;  		mSelectThisID = obj_id;  	}  } @@ -1731,7 +1735,7 @@ void LLInventoryPanel::updateSelection()  {  	if (mSelectThisID.notNull())  	{ -		setSelectionByID(mSelectThisID, false); +		setSelectionByID(mSelectThisID, mFocusSelection);  	}  } diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h index ad6010f09c..a019fc2231 100644 --- a/indra/newview/llinventorypanel.h +++ b/indra/newview/llinventorypanel.h @@ -269,6 +269,7 @@ protected:  	LLInventoryModel*			mInventory;  	LLInventoryObserver*		mInventoryObserver;  	LLInvPanelComplObserver*	mCompletionObserver; +	bool						mFocusSelection;  	bool						mAcceptsDragAndDrop;  	bool 						mAllowMultiSelect;  	bool 						mAllowDrag; @@ -366,27 +367,6 @@ private:      EViewsInitializationState	mViewsInitialized; // Whether views have been generated  }; - -class LLInventoryFavoriteItemsPanel : public LLInventoryPanel -{ -public: -    struct Params : public LLInitParam::Block<Params, LLInventoryPanel::Params> -    {}; - -    void initFromParams(const Params& p); -    bool isSelectionRemovable() { return false; } -    void setSelectCallback(const boost::function<void(const std::deque<LLFolderViewItem*>& items, BOOL user_action)>& cb); - -protected: -    LLInventoryFavoriteItemsPanel(const Params& params); -    ~LLInventoryFavoriteItemsPanel() { mFolderChangedSignal.disconnect(); } -    void updateFavoritesRootFolder(); - -    boost::signals2::connection mFolderChangedSignal; -    boost::function<void(const std::deque<LLFolderViewItem*>& items, BOOL user_action)> mSelectionCallback; -    friend class LLUICtrlFactory; -}; -  /************************************************************************/  /* Asset Pre-Filtered Inventory Panel related class                     */  /* Exchanges filter's flexibility for speed of generation and           */ diff --git a/indra/newview/lllandmarkactions.cpp b/indra/newview/lllandmarkactions.cpp index c243f8b4f0..a17dc674ac 100644 --- a/indra/newview/lllandmarkactions.cpp +++ b/indra/newview/lllandmarkactions.cpp @@ -228,23 +228,6 @@ LLViewerInventoryItem* LLLandmarkActions::findLandmarkForAgentPos()  	return findLandmarkForGlobalPos(gAgent.getPositionGlobal());  } -bool LLLandmarkActions::canCreateLandmarkHere() -{ -	LLParcel* agent_parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); -	if(!agent_parcel) -	{ -		LL_WARNS() << "No agent region" << LL_ENDL; -		return false; -	} -	if (agent_parcel->getAllowLandmark() -		|| LLViewerParcelMgr::isParcelOwnedByAgent(agent_parcel, GP_LAND_ALLOW_LANDMARK)) -	{ -		return true; -	} - -	return false; -} -  void LLLandmarkActions::createLandmarkHere(  	const std::string& name,   	const std::string& desc,  @@ -261,11 +244,6 @@ void LLLandmarkActions::createLandmarkHere(  		LL_WARNS() << "No agent parcel" << LL_ENDL;  		return;  	} -	if (!canCreateLandmarkHere()) -	{ -		LLNotificationsUtil::add("CannotCreateLandmarkNotOwner"); -		return; -	}  	create_inventory_item(gAgent.getID(), gAgent.getSessionID(),  		folder_id, LLTransactionID::tnull, diff --git a/indra/newview/lllandmarkactions.h b/indra/newview/lllandmarkactions.h index 870d92811e..ae7b072fcb 100644 --- a/indra/newview/lllandmarkactions.h +++ b/indra/newview/lllandmarkactions.h @@ -72,12 +72,6 @@ public:  	 */  	static LLViewerInventoryItem* findLandmarkForAgentPos(); - -	/** -	 * @brief Checks whether agent has rights to create landmark for current parcel. -	 */ -	static bool canCreateLandmarkHere(); -  	/**  	 * @brief Creates landmark for current parcel.  	 */ diff --git a/indra/newview/lllandmarklist.cpp b/indra/newview/lllandmarklist.cpp index 543d2a087f..9106d4e986 100644 --- a/indra/newview/lllandmarklist.cpp +++ b/indra/newview/lllandmarklist.cpp @@ -74,6 +74,16 @@ LLLandmark* LLLandmarkList::getAsset(const LLUUID& asset_uuid, loaded_callback_t  		{  			return NULL;  		} + +        if (cb) +        { +            // Multiple different sources can request same landmark, +            // mLoadedCallbackMap is a multimap that allows multiple pairs with same key +            // Todo: this might need to be improved to not hold identical callbacks multiple times +            loaded_callback_map_t::value_type vt(asset_uuid, cb); +            mLoadedCallbackMap.insert(vt); +        } +  	    if ( mWaitList.find(asset_uuid) != mWaitList.end() )  		{              // Landmark is sheduled for download, but not requested yet @@ -89,12 +99,6 @@ LLLandmark* LLLandmarkList::getAsset(const LLUUID& asset_uuid, loaded_callback_t  				return NULL;  			}  		} -		 -		if (cb) -		{ -			loaded_callback_map_t::value_type vt(asset_uuid, cb); -			mLoadedCallbackMap.insert(vt); -		}          if (mRequestedList.size() > MAX_SIMULTANEOUS_REQUESTS)          { @@ -132,36 +136,49 @@ void LLLandmarkList::processGetAssetReply(  		LLVFile file(vfs, uuid, type);  		S32 file_length = file.getSize(); -		std::vector<char> buffer(file_length + 1); -		file.read( (U8*)&buffer[0], file_length); -		buffer[ file_length ] = 0; +        if (file_length > 0) +        { +            std::vector<char> buffer(file_length + 1); +            file.read((U8*)&buffer[0], file_length); +            buffer[file_length] = 0; -		LLLandmark* landmark = LLLandmark::constructFromString(&buffer[0]); -		if (landmark) -		{ -			gLandmarkList.mList[ uuid ] = landmark; -			gLandmarkList.mRequestedList.erase(uuid); -			 -			LLVector3d pos; -			if(!landmark->getGlobalPos(pos)) -			{ -				LLUUID region_id; -				if(landmark->getRegionID(region_id)) -				{ -					LLLandmark::requestRegionHandle( -						gMessageSystem, -						gAgent.getRegionHost(), -						region_id, -						boost::bind(&LLLandmarkList::onRegionHandle, &gLandmarkList, uuid)); -				} - -				// the callback will be called when we get the region handle. -			} -			else -			{ -				gLandmarkList.makeCallbacks(uuid); -			} -		} +            LLLandmark* landmark = LLLandmark::constructFromString(&buffer[0], buffer.size()); +            if (landmark) +            { +                gLandmarkList.mList[uuid] = landmark; +                gLandmarkList.mRequestedList.erase(uuid); + +                LLVector3d pos; +                if (!landmark->getGlobalPos(pos)) +                { +                    LLUUID region_id; +                    if (landmark->getRegionID(region_id)) +                    { +                        LLLandmark::requestRegionHandle( +                            gMessageSystem, +                            gAgent.getRegionHost(), +                            region_id, +                            boost::bind(&LLLandmarkList::onRegionHandle, &gLandmarkList, uuid)); +                    } + +                    // the callback will be called when we get the region handle. +                } +                else +                { +                    gLandmarkList.makeCallbacks(uuid); +                } +            } +            else +            { +                // failed to parse, shouldn't happen +                gLandmarkList.eraseCallbacks(uuid); +            } +        } +        else +        { +            // got a good status, but no file, shouldn't happen +            gLandmarkList.eraseCallbacks(uuid); +        }  	}  	else  	{ @@ -179,7 +196,7 @@ void LLLandmarkList::processGetAssetReply(  		gLandmarkList.mBadList.insert(uuid);          gLandmarkList.mRequestedList.erase(uuid); //mBadList effectively blocks any load, so no point keeping id in requests -        // todo: this should clean mLoadedCallbackMap! +        gLandmarkList.eraseCallbacks(uuid);  	}      // getAssetData can fire callback immediately, causing @@ -223,32 +240,39 @@ BOOL LLLandmarkList::assetExists(const LLUUID& asset_uuid)  void LLLandmarkList::onRegionHandle(const LLUUID& landmark_id)  {  	LLLandmark* landmark = getAsset(landmark_id); - -	if (!landmark) -	{ -		LL_WARNS() << "Got region handle but the landmark not found." << LL_ENDL; -		return; -	} +    if (!landmark) +    { +        LL_WARNS() << "Got region handle but the landmark " << landmark_id << " not found." << LL_ENDL; +        eraseCallbacks(landmark_id); +        return; +    }  	// Calculate landmark global position.  	// This should succeed since the region handle is available.  	LLVector3d pos;  	if (!landmark->getGlobalPos(pos))  	{ -		LL_WARNS() << "Got region handle but the landmark global position is still unknown." << LL_ENDL; -		return; +        LL_WARNS() << "Got region handle but the landmark " << landmark_id << " global position is still unknown." << LL_ENDL; +        eraseCallbacks(landmark_id); +        return;  	} +    // Call this even if no landmark exists to clean mLoadedCallbackMap  	makeCallbacks(landmark_id);  } +void LLLandmarkList::eraseCallbacks(const LLUUID& landmark_id) +{ +    mLoadedCallbackMap.erase(landmark_id); +} +  void LLLandmarkList::makeCallbacks(const LLUUID& landmark_id)  {  	LLLandmark* landmark = getAsset(landmark_id);  	if (!landmark)  	{ -		LL_WARNS() << "Landmark to make callbacks for not found." << LL_ENDL; +		LL_WARNS() << "Landmark " << landmark_id << " to make callbacks for not found." << LL_ENDL;  	}  	// make all the callbacks here. diff --git a/indra/newview/lllandmarklist.h b/indra/newview/lllandmarklist.h index 2e7bd25610..4f3b11660d 100644 --- a/indra/newview/lllandmarklist.h +++ b/indra/newview/lllandmarklist.h @@ -65,6 +65,7 @@ public:  protected:  	void onRegionHandle(const LLUUID& landmark_id); +	void eraseCallbacks(const LLUUID& landmark_id);  	void makeCallbacks(const LLUUID& landmark_id);  	typedef std::map<LLUUID, LLLandmark*> landmark_list_t; diff --git a/indra/newview/lllocationinputctrl.cpp b/indra/newview/lllocationinputctrl.cpp index 83195e9e3f..d6f3068610 100644 --- a/indra/newview/lllocationinputctrl.cpp +++ b/indra/newview/lllocationinputctrl.cpp @@ -44,6 +44,7 @@  // newview includes  #include "llagent.h" +#include "llfloaterreg.h"  #include "llfloatersidepanelcontainer.h"  #include "llinventoryobserver.h"  #include "lllandmarkactions.h" @@ -653,7 +654,7 @@ void LLLocationInputCtrl::onAddLandmarkButtonClicked()  	}  	else  	{ -		LLFloaterSidePanelContainer::showPanel("places", LLSD().with("type", "create_landmark")); +		LLFloaterReg::showInstance("add_landmark");  	}  } @@ -1126,7 +1127,7 @@ void LLLocationInputCtrl::onLocationContextMenuItemClicked(const LLSD& userdata)  		if(!landmark)  		{ -			LLFloaterSidePanelContainer::showPanel("places", LLSD().with("type", "create_landmark")); +			LLFloaterReg::showInstance("add_landmark");  		}  		else  		{ diff --git a/indra/newview/llmediactrl.h b/indra/newview/llmediactrl.h index 958c76f261..bd24c47a4f 100644 --- a/indra/newview/llmediactrl.h +++ b/indra/newview/llmediactrl.h @@ -31,6 +31,7 @@  #include "lluictrl.h"  #include "llframetimer.h" +#include "llnotificationptr.h"  class LLViewBorder;  class LLUICtrlFactory; @@ -145,7 +146,7 @@ public:  		void setTextureSize(S32 width, S32 height); -		void showNotification(boost::shared_ptr<class LLNotification> notify); +		void showNotification(LLNotificationPtr notify);  		void hideNotification();  		void setTrustedContent(bool trusted); diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 3e8731dfe6..2c1c1191da 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -881,7 +881,7 @@ void LLMeshRepoThread::run()  		LL_WARNS(LOG_MESH) << "Convex decomposition unable to be loaded.  Expect severe problems." << LL_ENDL;  	} -	while (!LLApp::isQuitting()) +	while (!LLApp::isExiting())  	{  		// *TODO:  Revise sleep/wake strategy and try to move away  		// from polling operations in this thread.  We can sleep @@ -898,7 +898,7 @@ void LLMeshRepoThread::run()  		mSignal->wait(); -		if (LLApp::isQuitting()) +		if (LLApp::isExiting())  		{  			break;  		} @@ -1168,7 +1168,7 @@ void LLMeshRepoThread::loadMeshPhysicsShape(const LLUUID& mesh_id)  void LLMeshRepoThread::lockAndLoadMeshLOD(const LLVolumeParams& mesh_params, S32 lod)  { -	if (!LLAppViewer::isQuitting()) +	if (!LLAppViewer::isExiting())  	{  		loadMeshLOD(mesh_params, lod);  	} @@ -2654,7 +2654,7 @@ void LLMeshUploadThread::doWholeModelUpload()  			LL_DEBUGS(LOG_MESH) << "POST request issued." << LL_ENDL;  			mHttpRequest->update(0); -			while (! LLApp::isQuitting() && ! finished() && ! isDiscarded()) +			while (! LLApp::isExiting() && ! finished() && ! isDiscarded())  			{  				ms_sleep(sleep_time);  				sleep_time = llmin(250U, sleep_time + sleep_time); @@ -2703,7 +2703,7 @@ void LLMeshUploadThread::requestWholeModelFee()  		U32 sleep_time(10);  		mHttpRequest->update(0); -		while (! LLApp::isQuitting() && ! finished() && ! isDiscarded()) +		while (! LLApp::isExiting() && ! finished() && ! isDiscarded())  		{  			ms_sleep(sleep_time);  			sleep_time = llmin(250U, sleep_time + sleep_time); @@ -3149,7 +3149,7 @@ common_exit:  LLMeshHeaderHandler::~LLMeshHeaderHandler()  { -	if (!LLApp::isQuitting()) +	if (!LLApp::isExiting())  	{  		if (! mProcessed)  		{ @@ -3292,7 +3292,7 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* b  LLMeshLODHandler::~LLMeshLODHandler()  { -	if (! LLApp::isQuitting()) +	if (! LLApp::isExiting())  	{  		if (! mProcessed)  		{ @@ -3553,7 +3553,7 @@ void LLMeshRepository::shutdown()  		mUploads[i]->discard() ; //discard the uploading requests.  	} -	mThread->mSignal->signal(); +	mThread->mSignal->broadcast();  	while (!mThread->isStopped())  	{ @@ -4682,7 +4682,8 @@ void LLPhysicsDecomp::shutdown()  	if (mSignal)  	{  		mQuitting = true; -		mSignal->signal(); +		// There is only one wait(), but just in case 'broadcast' +		mSignal->broadcast();  		while (!isStopped())  		{ diff --git a/indra/newview/llmutelist.cpp b/indra/newview/llmutelist.cpp index 663a6071f7..4a8ef53a8b 100644 --- a/indra/newview/llmutelist.cpp +++ b/indra/newview/llmutelist.cpp @@ -726,7 +726,20 @@ void LLMuteList::requestFromServer(const LLUUID& agent_id)  	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());  	msg->nextBlockFast(_PREHASH_MuteData);  	msg->addU32Fast(_PREHASH_MuteCRC, crc.getCRC()); -	gAgent.sendReliableMessage(); + +    if (gDisconnected) +    { +        LL_WARNS() << "Trying to request mute list when disconnected!" << LL_ENDL; +        return; +    } +    if (!gAgent.getRegion()) +    { +        LL_WARNS() << "No region for agent yet, skipping mute list request!" << LL_ENDL; +        return; +    } +    // Double amount of retries due to this request happening during busy stage +    // Ideally this should be turned into a capability +    gMessageSystem->sendReliable(gAgent.getRegionHost(), LL_DEFAULT_RELIABLE_RETRIES * 2, TRUE, LL_PING_BASED_TIMEOUT_DUMMY, NULL, NULL);  }  //----------------------------------------------------------------------------- diff --git a/indra/newview/llnavigationbar.cpp b/indra/newview/llnavigationbar.cpp index 179c64b5c5..19dbbeb60e 100644 --- a/indra/newview/llnavigationbar.cpp +++ b/indra/newview/llnavigationbar.cpp @@ -58,6 +58,7 @@  #include "llweb.h"  #include "llhints.h" +#include "llfloatersidepanelcontainer.h"  #include "llinventorymodel.h"  #include "lllandmarkactions.h" @@ -290,6 +291,7 @@ BOOL LLNavigationBar::postBuild()  	mBtnBack	= getChild<LLPullButton>("back_btn");  	mBtnForward	= getChild<LLPullButton>("forward_btn");  	mBtnHome	= getChild<LLButton>("home_btn"); +	mBtnLandmarks = getChild<LLButton>("landmarks_btn");  	mCmbLocation= getChild<LLLocationInputCtrl>("location_combo"); @@ -305,6 +307,8 @@ BOOL LLNavigationBar::postBuild()  	mBtnHome->setClickedCallback(boost::bind(&LLNavigationBar::onHomeButtonClicked, this)); +	mBtnLandmarks->setClickedCallback(boost::bind(&LLNavigationBar::onLandmarksButtonClicked, this)); +  	mCmbLocation->setCommitCallback(boost::bind(&LLNavigationBar::onLocationSelection, this));  	mTeleportFinishConnection = LLViewerParcelMgr::getInstance()-> @@ -401,6 +405,12 @@ void LLNavigationBar::onHomeButtonClicked()  	gAgent.teleportHome();  } +void LLNavigationBar::onLandmarksButtonClicked() +{ +	LLFloaterReg::toggleInstanceOrBringToFront("places"); +	LLFloaterSidePanelContainer::showPanel("places", LLSD().with("type", "open_landmark_tab")); +} +  void LLNavigationBar::onTeleportHistoryMenuItemClicked(const LLSD& userdata)  {  	int idx = userdata.asInteger(); diff --git a/indra/newview/llnavigationbar.h b/indra/newview/llnavigationbar.h index a44c6dd699..646911a62c 100755 --- a/indra/newview/llnavigationbar.h +++ b/indra/newview/llnavigationbar.h @@ -119,6 +119,7 @@ private:  	void onNavigationButtonHeldUp(LLButton* nav_button);  	void onForwardButtonClicked();  	void onHomeButtonClicked(); +	void onLandmarksButtonClicked();  	void onLocationSelection();  	void onLocationPrearrange(const LLSD& data);  	void onTeleportFinished(const LLVector3d& global_agent_pos); @@ -144,6 +145,7 @@ private:  	LLPullButton*				mBtnBack;  	LLPullButton*				mBtnForward;  	LLButton*					mBtnHome; +	LLButton*					mBtnLandmarks;  	LLLocationInputCtrl*		mCmbLocation;  	LLRect						mDefaultNbRect;  	LLRect						mDefaultFpRect; diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp index 272e7ae351..c1b622ffff 100644 --- a/indra/newview/lloutfitgallery.cpp +++ b/indra/newview/lloutfitgallery.cpp @@ -67,6 +67,7 @@ LLOutfitGallery::LLOutfitGallery(const LLOutfitGallery::Params& p)        mOutfitsObserver(NULL),        mScrollPanel(NULL),        mGalleryPanel(NULL), +      mLastRowPanel(NULL),        mGalleryCreated(false),        mRowCount(0),        mItemsAddedCount(0), @@ -166,9 +167,7 @@ bool compareGalleryItem(LLOutfitGalleryItem* item1, LLOutfitGalleryItem* item2)          std::string name1 = item1->getItemName();          std::string name2 = item2->getItemName(); -        LLStringUtil::toUpper(name1); -        LLStringUtil::toUpper(name2); -        return name1 < name2; +        return (LLStringUtil::compareDict(name1, name2) < 0);      }      else      { @@ -241,7 +240,15 @@ void LLOutfitGallery::removeLastRow()      mGalleryPanel->removeChild(mLastRowPanel);      mUnusedRowPanels.push_back(mLastRowPanel);      mRowPanels.pop_back(); -    mLastRowPanel = mRowPanels.back(); +    if (mRowPanels.size() > 0) +    { +        // Just removed last row +        mLastRowPanel = mRowPanels.back(); +    } +    else +    { +        mLastRowPanel = NULL; +    }  }  LLPanel* LLOutfitGallery::addToRow(LLPanel* row_stack, LLOutfitGalleryItem* item, int pos, int hgap) @@ -1111,7 +1118,7 @@ void LLOutfitGallery::refreshOutfit(const LLUUID& category_id)          }      } -    if (mGalleryCreated && !LLApp::isQuitting()) +    if (mGalleryCreated && !LLApp::isExiting())      {          reArrangeRows();      } diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp index 71ab826e1c..423e57978a 100644 --- a/indra/newview/lloutfitslist.cpp +++ b/indra/newview/lloutfitslist.cpp @@ -59,10 +59,7 @@ bool LLOutfitTabNameComparator::compare(const LLAccordionCtrlTab* tab1, const LL  	std::string name1 = tab1->getTitle();  	std::string name2 = tab2->getTitle(); -	LLStringUtil::toUpper(name1); -	LLStringUtil::toUpper(name2); - -	return name1 < name2; +    return (LLStringUtil::compareDict(name1, name2) < 0);  }  struct outfit_accordion_tab_params : public LLInitParam::Block<outfit_accordion_tab_params, LLAccordionCtrlTab::Params> diff --git a/indra/newview/llpaneleditsky.cpp b/indra/newview/llpaneleditsky.cpp index 2e26b69144..a169712bd8 100644 --- a/indra/newview/llpaneleditsky.cpp +++ b/indra/newview/llpaneleditsky.cpp @@ -69,11 +69,15 @@ namespace      const std::string   FIELD_SKY_GLOW_SIZE("glow_size");      const std::string   FIELD_SKY_STAR_BRIGHTNESS("star_brightness");      const std::string   FIELD_SKY_SUN_ROTATION("sun_rotation"); +    const std::string   FIELD_SKY_SUN_AZIMUTH("sun_azimuth"); +    const std::string   FIELD_SKY_SUN_ELEVATION("sun_elevation");      const std::string   FIELD_SKY_SUN_IMAGE("sun_image");      const std::string   FIELD_SKY_SUN_SCALE("sun_scale");      const std::string   FIELD_SKY_SUN_BEACON("sunbeacon");      const std::string   FIELD_SKY_MOON_BEACON("moonbeacon");      const std::string   FIELD_SKY_MOON_ROTATION("moon_rotation"); +    const std::string   FIELD_SKY_MOON_AZIMUTH("moon_azimuth"); +    const std::string   FIELD_SKY_MOON_ELEVATION("moon_elevation");      const std::string   FIELD_SKY_MOON_IMAGE("moon_image");      const std::string   FIELD_SKY_MOON_SCALE("moon_scale");      const std::string   FIELD_SKY_MOON_BRIGHTNESS("moon_brightness"); @@ -473,12 +477,16 @@ BOOL LLPanelSettingsSkySunMoonTab::postBuild()      getChild<LLUICtrl>(FIELD_SKY_GLOW_SIZE)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onGlowChanged(); });      getChild<LLUICtrl>(FIELD_SKY_STAR_BRIGHTNESS)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onStarBrightnessChanged(); });      getChild<LLUICtrl>(FIELD_SKY_SUN_ROTATION)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onSunRotationChanged(); }); +    getChild<LLUICtrl>(FIELD_SKY_SUN_AZIMUTH)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onSunAzimElevChanged(); }); +    getChild<LLUICtrl>(FIELD_SKY_SUN_ELEVATION)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onSunAzimElevChanged(); });      getChild<LLUICtrl>(FIELD_SKY_SUN_IMAGE)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onSunImageChanged(); });      getChild<LLUICtrl>(FIELD_SKY_SUN_SCALE)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onSunScaleChanged(); });      getChild<LLTextureCtrl>(FIELD_SKY_SUN_IMAGE)->setBlankImageAssetID(LLSettingsSky::GetBlankSunTextureId());      getChild<LLTextureCtrl>(FIELD_SKY_SUN_IMAGE)->setDefaultImageAssetID(LLSettingsSky::GetBlankSunTextureId());      getChild<LLTextureCtrl>(FIELD_SKY_SUN_IMAGE)->setAllowNoTexture(TRUE);      getChild<LLUICtrl>(FIELD_SKY_MOON_ROTATION)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onMoonRotationChanged(); }); +    getChild<LLUICtrl>(FIELD_SKY_MOON_AZIMUTH)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onMoonAzimElevChanged(); }); +    getChild<LLUICtrl>(FIELD_SKY_MOON_ELEVATION)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onMoonAzimElevChanged(); });      getChild<LLUICtrl>(FIELD_SKY_MOON_IMAGE)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onMoonImageChanged(); });      getChild<LLTextureCtrl>(FIELD_SKY_MOON_IMAGE)->setDefaultImageAssetID(LLSettingsSky::GetDefaultMoonTextureId());      getChild<LLTextureCtrl>(FIELD_SKY_MOON_IMAGE)->setBlankImageAssetID(LLSettingsSky::GetDefaultMoonTextureId()); @@ -537,13 +545,29 @@ void LLPanelSettingsSkySunMoonTab::refresh()      getChild<LLUICtrl>(FIELD_SKY_GLOW_FOCUS)->setValue(glow.mV[2] / SLIDER_SCALE_GLOW_B);      getChild<LLUICtrl>(FIELD_SKY_STAR_BRIGHTNESS)->setValue(mSkySettings->getStarBrightness()); -    getChild<LLVirtualTrackball>(FIELD_SKY_SUN_ROTATION)->setRotation(mSkySettings->getSunRotation());      getChild<LLTextureCtrl>(FIELD_SKY_SUN_IMAGE)->setValue(mSkySettings->getSunTextureId());      getChild<LLUICtrl>(FIELD_SKY_SUN_SCALE)->setValue(mSkySettings->getSunScale()); -    getChild<LLVirtualTrackball>(FIELD_SKY_MOON_ROTATION)->setRotation(mSkySettings->getMoonRotation());      getChild<LLTextureCtrl>(FIELD_SKY_MOON_IMAGE)->setValue(mSkySettings->getMoonTextureId());      getChild<LLUICtrl>(FIELD_SKY_MOON_SCALE)->setValue(mSkySettings->getMoonScale());      getChild<LLUICtrl>(FIELD_SKY_MOON_BRIGHTNESS)->setValue(mSkySettings->getMoonBrightness()); + +    // Sun rotation values +    F32 azimuth, elevation; +    LLQuaternion quat = mSkySettings->getSunRotation(); +    LLVirtualTrackball::getAzimuthAndElevationDeg(quat, azimuth, elevation); + +    getChild<LLVirtualTrackball>(FIELD_SKY_SUN_ROTATION)->setRotation(quat); +    getChild<LLUICtrl>(FIELD_SKY_SUN_AZIMUTH)->setValue(azimuth); +    getChild<LLUICtrl>(FIELD_SKY_SUN_ELEVATION)->setValue(elevation); + +    // Moon rotation values +    quat = mSkySettings->getMoonRotation(); +    LLVirtualTrackball::getAzimuthAndElevationDeg(quat, azimuth, elevation); + +    getChild<LLVirtualTrackball>(FIELD_SKY_MOON_ROTATION)->setRotation(quat); +    getChild<LLUICtrl>(FIELD_SKY_MOON_AZIMUTH)->setValue(azimuth); +    getChild<LLUICtrl>(FIELD_SKY_MOON_ELEVATION)->setValue(elevation); +  }  //------------------------------------------------------------------------- @@ -583,10 +607,47 @@ void LLPanelSettingsSkySunMoonTab::onStarBrightnessChanged()  void LLPanelSettingsSkySunMoonTab::onSunRotationChanged()  { -    if (!mSkySettings) return; -    mSkySettings->setSunRotation(getChild<LLVirtualTrackball>(FIELD_SKY_SUN_ROTATION)->getRotation()); -    mSkySettings->update(); -    setIsDirty(); +    LLQuaternion quat = getChild<LLVirtualTrackball>(FIELD_SKY_SUN_ROTATION)->getRotation(); + +    F32 azimuth, elevation; +    LLVirtualTrackball::getAzimuthAndElevationDeg(quat, azimuth, elevation); +    getChild<LLUICtrl>(FIELD_SKY_SUN_AZIMUTH)->setValue(azimuth); +    getChild<LLUICtrl>(FIELD_SKY_SUN_ELEVATION)->setValue(elevation); +    if (mSkySettings) +    { +        mSkySettings->setSunRotation(quat); +        mSkySettings->update(); +        setIsDirty(); +    } +} + +void LLPanelSettingsSkySunMoonTab::onSunAzimElevChanged() +{ +    F32 azimuth = getChild<LLUICtrl>(FIELD_SKY_SUN_AZIMUTH)->getValue().asReal(); +    F32 elevation = getChild<LLUICtrl>(FIELD_SKY_SUN_ELEVATION)->getValue().asReal(); +    LLQuaternion quat; + +    azimuth *= DEG_TO_RAD; +    elevation *= DEG_TO_RAD; + +    if (is_approx_zero(elevation)) +    { +        elevation = F_APPROXIMATELY_ZERO; +    } + +    quat.setAngleAxis(-elevation, 0, 1, 0); +    LLQuaternion az_quat; +    az_quat.setAngleAxis(F_TWO_PI - azimuth, 0, 0, 1); +    quat *= az_quat; + +    getChild<LLVirtualTrackball>(FIELD_SKY_SUN_ROTATION)->setRotation(quat); + +    if (mSkySettings) +    { +        mSkySettings->setSunRotation(quat); +        mSkySettings->update(); +        setIsDirty(); +    }  }  void LLPanelSettingsSkySunMoonTab::onSunScaleChanged() @@ -607,10 +668,48 @@ void LLPanelSettingsSkySunMoonTab::onSunImageChanged()  void LLPanelSettingsSkySunMoonTab::onMoonRotationChanged()  { -    if (!mSkySettings) return; -    mSkySettings->setMoonRotation(getChild<LLVirtualTrackball>(FIELD_SKY_MOON_ROTATION)->getRotation()); -    mSkySettings->update(); -    setIsDirty(); +    LLQuaternion quat = getChild<LLVirtualTrackball>(FIELD_SKY_MOON_ROTATION)->getRotation(); + +    F32 azimuth, elevation; +    LLVirtualTrackball::getAzimuthAndElevationDeg(quat, azimuth, elevation); +    getChild<LLUICtrl>(FIELD_SKY_MOON_AZIMUTH)->setValue(azimuth); +    getChild<LLUICtrl>(FIELD_SKY_MOON_ELEVATION)->setValue(elevation); + +    if (mSkySettings) +    { +        mSkySettings->setMoonRotation(quat); +        mSkySettings->update(); +        setIsDirty(); +    } +} + +void LLPanelSettingsSkySunMoonTab::onMoonAzimElevChanged() +{ +    F32 azimuth = getChild<LLUICtrl>(FIELD_SKY_MOON_AZIMUTH)->getValue().asReal(); +    F32 elevation = getChild<LLUICtrl>(FIELD_SKY_MOON_ELEVATION)->getValue().asReal(); +    LLQuaternion quat; + +    azimuth *= DEG_TO_RAD; +    elevation *= DEG_TO_RAD; + +    if (is_approx_zero(elevation)) +    { +        elevation = F_APPROXIMATELY_ZERO; +    } + +    quat.setAngleAxis(-elevation, 0, 1, 0); +    LLQuaternion az_quat; +    az_quat.setAngleAxis(F_TWO_PI- azimuth, 0, 0, 1); +    quat *= az_quat; + +    getChild<LLVirtualTrackball>(FIELD_SKY_MOON_ROTATION)->setRotation(quat); + +    if (mSkySettings) +    { +        mSkySettings->setMoonRotation(quat); +        mSkySettings->update(); +        setIsDirty(); +    }  }  void LLPanelSettingsSkySunMoonTab::onMoonImageChanged() diff --git a/indra/newview/llpaneleditsky.h b/indra/newview/llpaneleditsky.h index 801fb8b9b2..cb63d40b0c 100644 --- a/indra/newview/llpaneleditsky.h +++ b/indra/newview/llpaneleditsky.h @@ -124,9 +124,11 @@ private:      void                    onGlowChanged();      void                    onStarBrightnessChanged();      void                    onSunRotationChanged(); +    void                    onSunAzimElevChanged();      void                    onSunScaleChanged();      void                    onSunImageChanged();      void                    onMoonRotationChanged(); +    void                    onMoonAzimElevChanged();      void                    onMoonScaleChanged();      void                    onMoonBrightnessChanged();      void                    onMoonImageChanged(); diff --git a/indra/newview/llpanellandmarkinfo.cpp b/indra/newview/llpanellandmarkinfo.cpp index 6751c25fb9..880323ce16 100644 --- a/indra/newview/llpanellandmarkinfo.cpp +++ b/indra/newview/llpanellandmarkinfo.cpp @@ -52,7 +52,6 @@  typedef std::pair<LLUUID, std::string> folder_pair_t;  static bool cmp_folders(const folder_pair_t& left, const folder_pair_t& right); -static void collectLandmarkFolders(LLInventoryModel::cat_array_t& cats);  static LLPanelInjector<LLPanelLandmarkInfo> t_landmark_info("panel_landmark_info"); @@ -107,6 +106,18 @@ void LLPanelLandmarkInfo::resetLocation()  // virtual  void LLPanelLandmarkInfo::setInfoType(EInfoType type)  { +    LLUUID dest_folder; +    setInfoType(type, dest_folder); +} + +// Sets CREATE_LANDMARK infotype and creates landmark at desired folder +void LLPanelLandmarkInfo::setInfoAndCreateLandmark(const LLUUID& fodler_id) +{ +    setInfoType(CREATE_LANDMARK, fodler_id); +} + +void LLPanelLandmarkInfo::setInfoType(EInfoType type, const LLUUID &folder_id) +{  	LLPanel* landmark_info_panel = getChild<LLPanel>("landmark_info_panel");  	bool is_info_type_create_landmark = type == CREATE_LANDMARK; @@ -183,7 +194,7 @@ void LLPanelLandmarkInfo::setInfoType(EInfoType type)  			// remote parcel request to complete.  			if (!LLLandmarkActions::landmarkAlreadyExists())  			{ -				createLandmark(LLUUID()); +				createLandmark(folder_id);  			}  		}  		break; @@ -504,7 +515,7 @@ static bool cmp_folders(const folder_pair_t& left, const folder_pair_t& right)  	return left.second < right.second;  } -static void collectLandmarkFolders(LLInventoryModel::cat_array_t& cats) +void LLPanelLandmarkInfo::collectLandmarkFolders(LLInventoryModel::cat_array_t& cats)  {  	LLUUID landmarks_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_LANDMARK); @@ -517,16 +528,20 @@ static void collectLandmarkFolders(LLInventoryModel::cat_array_t& cats)  		items,  		LLInventoryModel::EXCLUDE_TRASH,  		is_category); +} -	// Add the "My Favorites" category. -	LLUUID favorites_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE); -	LLViewerInventoryCategory* favorites_cat = gInventory.getCategory(favorites_id); -	if (!favorites_cat) -	{ -		LL_WARNS() << "Cannot find the favorites folder" << LL_ENDL; -	} -	else -	{ -		cats.push_back(favorites_cat); -	} +/* virtual */ void LLUpdateLandmarkParent::fire(const LLUUID& inv_item_id) +{ +	LLInventoryModel::update_list_t update; +	LLInventoryModel::LLCategoryUpdate old_folder(mItem->getParentUUID(), -1); +	update.push_back(old_folder); +	LLInventoryModel::LLCategoryUpdate new_folder(mNewParentId, 1); +	update.push_back(new_folder); +	gInventory.accountForUpdate(update); + +	mItem->setParent(mNewParentId); +	mItem->updateParentOnServer(FALSE); + +	gInventory.updateItem(mItem); +	gInventory.notifyObservers();  } diff --git a/indra/newview/llpanellandmarkinfo.h b/indra/newview/llpanellandmarkinfo.h index 9712736182..f727f286b5 100644 --- a/indra/newview/llpanellandmarkinfo.h +++ b/indra/newview/llpanellandmarkinfo.h @@ -28,6 +28,7 @@  #define LL_LLPANELLANDMARKINFO_H  #include "llpanelplaceinfo.h" +#include "llinventorymodel.h"  class LLComboBox;  class LLLineEditor; @@ -43,8 +44,12 @@ public:  	/*virtual*/ void resetLocation(); +    // If landmark doesn't exists, will create it at default folder  	/*virtual*/ void setInfoType(EInfoType type); +    // Sets CREATE_LANDMARK infotype and creates landmark at desired folder +    void setInfoAndCreateLandmark(const LLUUID& fodler_id); +  	/*virtual*/ void processParcelInfo(const LLParcelData& parcel_data);  	// Displays landmark owner, creator and creation date info. @@ -59,13 +64,19 @@ public:  	// Select current landmark folder in combobox.  	BOOL setLandmarkFolder(const LLUUID& id); -	// Create a landmark for the current location -	// in a folder specified by folder_id. -	void createLandmark(const LLUUID& folder_id); - +	typedef std::vector<LLPointer<LLViewerInventoryCategory> > cat_array_t;  	static std::string getFullFolderName(const LLViewerInventoryCategory* cat); +	static void collectLandmarkFolders(LLInventoryModel::cat_array_t& cats);  private: +    // Create a landmark for the current location +    // in a folder specified by folder_id. +    // Expects title and description to be initialized +    void createLandmark(const LLUUID& folder_id); + +    // If landmark doesn't exists, will create it at specified folder +    void setInfoType(EInfoType type, const LLUUID &folder_id); +  	void populateFoldersList();  	LLTextBox*			mOwner; @@ -77,4 +88,17 @@ private:  	LLComboBox*			mFolderCombo;  }; +class LLUpdateLandmarkParent : public LLInventoryCallback +{ +public: +	LLUpdateLandmarkParent(LLPointer<LLViewerInventoryItem> item, LLUUID new_parent) : +		mItem(item), +		mNewParentId(new_parent) +	{}; +	/* virtual */ void fire(const LLUUID& inv_item_id); + +private: +	LLPointer<LLViewerInventoryItem> mItem; +	LLUUID mNewParentId; +};  #endif // LL_LLPANELLANDMARKINFO_H diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp index ccd8497484..e698a61fef 100644 --- a/indra/newview/llpanellandmarks.cpp +++ b/indra/newview/llpanellandmarks.cpp @@ -36,12 +36,11 @@  #include "llregionhandle.h"  #include "llaccordionctrl.h" -#include "llaccordionctrltab.h"  #include "llagent.h"  #include "llagentpicksinfo.h"  #include "llagentui.h" +#include "llavataractions.h"  #include "llcallbacklist.h" -#include "lldndbutton.h"  #include "llfloatersidepanelcontainer.h"  #include "llfloaterworldmap.h"  #include "llfolderviewitem.h" @@ -60,15 +59,8 @@  // Not yet implemented; need to remove buildPanel() from constructor when we switch  //static LLRegisterPanelClassWrapper<LLLandmarksPanel> t_landmarks("panel_landmarks"); -static const std::string OPTIONS_BUTTON_NAME = "options_gear_btn"; -static const std::string ADD_BUTTON_NAME = "add_btn"; -static const std::string ADD_FOLDER_BUTTON_NAME = "add_folder_btn"; -static const std::string TRASH_BUTTON_NAME = "trash_btn"; - -  // helper functions  static void filter_list(LLPlacesInventoryPanel* inventory_list, const std::string& string); -static bool category_has_descendents(LLPlacesInventoryPanel* inventory_list);  static void collapse_all_folders(LLFolderView* root_folder);  static void expand_all_folders(LLFolderView* root_folder);  static bool has_expanded_folders(LLFolderView* root_folder); @@ -149,69 +141,37 @@ void LLOpenFolderByID::doFolder(LLFolderViewFolder* folder)  	}  } -/** - * Bridge to support knowing when the inventory has changed to update Landmarks tab - * ShowFolderState filter setting to show all folders when the filter string is empty and - * empty folder message when Landmarks inventory category has no children. - * Ensures that "Landmarks" folder in the Library is open on strart up. - */ -class LLLandmarksPanelObserver : public LLInventoryObserver -{ -public: -	LLLandmarksPanelObserver(LLLandmarksPanel* lp) -	:	mLP(lp), -	 	mIsLibraryLandmarksOpen(false) -	{} -	virtual ~LLLandmarksPanelObserver() {} -	/*virtual*/ void changed(U32 mask); - -private: -	LLLandmarksPanel* mLP; -	bool mIsLibraryLandmarksOpen; -}; - -void LLLandmarksPanelObserver::changed(U32 mask) +LLLandmarksPanel::LLLandmarksPanel() +	:	LLPanelPlacesTab() +	,	mLandmarksInventoryPanel(NULL) +	,	mCurrentSelectedList(NULL) +	,	mGearFolderMenu(NULL) +	,	mGearLandmarkMenu(NULL) +	,	mSortingMenu(NULL) +	,	mAddMenu(NULL) +	,	isLandmarksPanel(true)  { -	mLP->updateShowFolderState(); - -	LLPlacesInventoryPanel* library = mLP->getLibraryInventoryPanel(); -	if (!mIsLibraryLandmarksOpen && library) -	{ -		// Search for "Landmarks" folder in the Library and open it once on start up. See EXT-4827. -		const LLUUID &landmarks_cat = gInventory.findLibraryCategoryUUIDForType(LLFolderType::FT_LANDMARK, false); -		if (landmarks_cat.notNull()) -		{ -			LLOpenFolderByID opener(landmarks_cat); -			library->getRootFolder()->applyFunctorRecursively(opener); -			mIsLibraryLandmarksOpen = opener.isFolderOpen(); -		} -	} +	buildFromFile("panel_landmarks.xml");  } -LLLandmarksPanel::LLLandmarksPanel() +LLLandmarksPanel::LLLandmarksPanel(bool is_landmark_panel)  	:	LLPanelPlacesTab() -	,	mFavoritesInventoryPanel(NULL)  	,	mLandmarksInventoryPanel(NULL) -	,	mMyInventoryPanel(NULL) -	,	mLibraryInventoryPanel(NULL)  	,	mCurrentSelectedList(NULL) -	,	mListCommands(NULL) -	,	mGearButton(NULL)  	,	mGearFolderMenu(NULL)  	,	mGearLandmarkMenu(NULL) +	,	mSortingMenu(NULL) +	,	mAddMenu(NULL) +	,	isLandmarksPanel(is_landmark_panel)  { -	mInventoryObserver = new LLLandmarksPanelObserver(this); -	gInventory.addObserver(mInventoryObserver); - -	buildFromFile( "panel_landmarks.xml"); +	if (is_landmark_panel) +	{ +		buildFromFile("panel_landmarks.xml"); +	}  }  LLLandmarksPanel::~LLLandmarksPanel()  { -	if (gInventory.containsObserver(mInventoryObserver)) -	{ -		gInventory.removeObserver(mInventoryObserver); -	}  }  BOOL LLLandmarksPanel::postBuild() @@ -221,17 +181,7 @@ BOOL LLLandmarksPanel::postBuild()  	// mast be called before any other initXXX methods to init Gear menu  	initListCommandsHandlers(); - -	initFavoritesInventoryPanel();  	initLandmarksInventoryPanel(); -	initMyInventoryPanel(); -	initLibraryInventoryPanel(); - -	LLAccordionCtrl* accordion = getChild<LLAccordionCtrl>("landmarks_accordion"); -	if (accordion) -	{ -		accordion->setSkipScrollToChild(true); -	}  	return TRUE;  } @@ -239,30 +189,10 @@ BOOL LLLandmarksPanel::postBuild()  // virtual  void LLLandmarksPanel::onSearchEdit(const std::string& string)  { -	// give FolderView a chance to be refreshed. So, made all accordions visible -	for (accordion_tabs_t::const_iterator iter = mAccordionTabs.begin(); iter != mAccordionTabs.end(); ++iter) -	{ -		LLAccordionCtrlTab* tab = *iter; -		tab->setVisible(TRUE); - -		// expand accordion to see matched items in each one. See EXT-2014. -		if (string != "") -		{ -			tab->changeOpenClose(false); -		} - -		LLPlacesInventoryPanel* inventory_list = dynamic_cast<LLPlacesInventoryPanel*>(tab->getAccordionView()); -		if (NULL == inventory_list) continue; - -		filter_list(inventory_list, string); -	} +	filter_list(mCurrentSelectedList, string);  	if (sFilterSubString != string)  		sFilterSubString = string; - -	// show all folders in Landmarks Accordion for empty filter -	// only if Landmarks inventory folder is not empty -	updateShowFolderState();  }  // virtual @@ -274,11 +204,6 @@ void LLLandmarksPanel::onShowOnMap()  		return;  	} -	// Disable the "Map" button because loading landmark can take some time. -	// During this time the button is useless. It will be enabled on callback finish -	// or upon switching to other item. -	mShowOnMapBtn->setEnabled(FALSE); -  	doActionOnCurSelectedLandmark(boost::bind(&LLLandmarksPanel::doShowOnMap, this, _1));  } @@ -303,6 +228,12 @@ void LLLandmarksPanel::onTeleport()  	}  } +/*virtual*/ +void LLLandmarksPanel::onRemoveSelected() +{ +    onClipboardAction("delete"); +} +  // virtual  bool LLLandmarksPanel::isSingleItemSelected()  { @@ -322,86 +253,55 @@ bool LLLandmarksPanel::isSingleItemSelected()  }  // virtual -void LLLandmarksPanel::updateVerbs() -{ -	if (!isTabVisible())  -		return; - -	bool landmark_selected = isLandmarkSelected(); -	mTeleportBtn->setEnabled(landmark_selected && isActionEnabled("teleport")); -	mShowProfile->setEnabled(landmark_selected && isActionEnabled("more_info")); -	mShowOnMapBtn->setEnabled(landmark_selected && isActionEnabled("show_on_map")); - -	// TODO: mantipov: Uncomment when mShareBtn is supported -	// Share button should be enabled when neither a folder nor a landmark is selected -	//mShareBtn->setEnabled(NULL != current_item); - -	updateListCommands(); +LLToggleableMenu* LLLandmarksPanel::getSelectionMenu() +{ +    LLToggleableMenu* menu = mGearFolderMenu; + +    if (mCurrentSelectedList) +    { +        LLFolderViewModelItemInventory* listenerp = getCurSelectedViewModelItem(); +        if (!listenerp) +            return menu; + +        if (listenerp->getInventoryType() == LLInventoryType::IT_LANDMARK) +        { +            menu = mGearLandmarkMenu; +        } +    } +    return menu;  } -void LLLandmarksPanel::onSelectionChange(LLPlacesInventoryPanel* inventory_list, const std::deque<LLFolderViewItem*> &items, BOOL user_action) +// virtual +LLToggleableMenu* LLLandmarksPanel::getSortingMenu()  { -	if (user_action && (items.size() > 0)) -	{ -		deselectOtherThan(inventory_list); -		mCurrentSelectedList = inventory_list; -	} -	updateVerbs(); +    return mSortingMenu;  } -void LLLandmarksPanel::onSelectorButtonClicked() +// virtual +LLToggleableMenu* LLLandmarksPanel::getCreateMenu()  { -	// TODO: mantipov: update getting of selected item -	// TODO: bind to "i" button -	LLFolderViewItem* cur_item = mFavoritesInventoryPanel->getRootFolder()->getCurSelectedItem(); -	if (!cur_item) return; - -	LLFolderViewModelItemInventory* listenerp = static_cast<LLFolderViewModelItemInventory*>(cur_item->getViewModelItem()); -	if (listenerp->getInventoryType() == LLInventoryType::IT_LANDMARK) -	{ -		LLSD key; -		key["type"] = "landmark"; -		key["id"] = listenerp->getUUID(); - -		LLFloaterSidePanelContainer::showPanel("places", key); -	} +    return mAddMenu;  } -void LLLandmarksPanel::updateShowFolderState() +void LLLandmarksPanel::updateVerbs()  { -	bool show_all_folders =   mLandmarksInventoryPanel->getFilterSubString().empty(); -	if (show_all_folders) +	if (sRemoveBtn)  	{ -		show_all_folders = category_has_descendents(mLandmarksInventoryPanel); +		sRemoveBtn->setEnabled(isActionEnabled("delete") && (isFolderSelected() || isLandmarkSelected()));  	} - -	mLandmarksInventoryPanel->setShowFolderState(show_all_folders ? -		LLInventoryFilter::SHOW_ALL_FOLDERS : -		LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS -		);  }  void LLLandmarksPanel::setItemSelected(const LLUUID& obj_id, BOOL take_keyboard_focus)  { -	if (selectItemInAccordionTab(mFavoritesInventoryPanel, "tab_favorites", obj_id, take_keyboard_focus)) -	{ +	if (!mCurrentSelectedList)  		return; -	} -	if (selectItemInAccordionTab(mLandmarksInventoryPanel, "tab_landmarks", obj_id, take_keyboard_focus)) -	{ -		return; -	} - -	if (selectItemInAccordionTab(mMyInventoryPanel, "tab_inventory", obj_id, take_keyboard_focus)) -	{ -		return; -	} - -	if (selectItemInAccordionTab(mLibraryInventoryPanel, "tab_library", obj_id, take_keyboard_focus)) -	{ +	LLFolderView* root = mCurrentSelectedList->getRootFolder(); +	LLFolderViewItem* item = mCurrentSelectedList->getItemByID(obj_id); +	if (!item)  		return; -	} +	root->setSelection(item, FALSE, take_keyboard_focus); +	root->scrollToShowSelection();  }  ////////////////////////////////////////////////////////////////////////// @@ -420,18 +320,6 @@ bool LLLandmarksPanel::isFolderSelected() const  	return current_item && (current_item->getInventoryType() == LLInventoryType::IT_CATEGORY);  } -bool LLLandmarksPanel::isReceivedFolderSelected() const -{ -	// Received Folder can be only in Landmarks accordion -	if (mCurrentSelectedList != mLandmarksInventoryPanel) return false; - -	// *TODO: it should be filled with logic when EXT-976 is done. - -	LL_WARNS() << "Not implemented yet until EXT-976 is done." << LL_ENDL; - -	return false; -} -  void LLLandmarksPanel::doActionOnCurSelectedLandmark(LLLandmarkList::loaded_callback_t cb)  {  	LLFolderViewModelItemInventory* cur_item = getCurSelectedViewModelItem(); @@ -461,36 +349,6 @@ LLFolderViewModelItemInventory* LLLandmarksPanel::getCurSelectedViewModelItem()  } -LLFolderViewItem* LLLandmarksPanel::selectItemInAccordionTab(LLPlacesInventoryPanel* inventory_list, -															 const std::string& tab_name, -															 const LLUUID& obj_id, -															 BOOL take_keyboard_focus) const -{ -	if (!inventory_list) -		return NULL; - -	LLFolderView* root = inventory_list->getRootFolder(); - -	LLFolderViewItem* item = inventory_list->getItemByID(obj_id); -	if (!item) -		return NULL; - -	LLAccordionCtrlTab* tab = getChild<LLAccordionCtrlTab>(tab_name); -	if (!tab->isExpanded()) -	{ -		tab->changeOpenClose(false); -	} - -	root->setSelection(item, FALSE, take_keyboard_focus); - -	LLAccordionCtrl* accordion = getChild<LLAccordionCtrl>("landmarks_accordion"); -	LLRect screen_rc; -	localRectToScreen(item->getRect(), &screen_rc); -	accordion->notifyParent(LLSD().with("scrollToShowRect", screen_rc.getValue())); - -	return item; -} -  void LLLandmarksPanel::updateSortOrder(LLInventoryPanel* panel, bool byDate)  {  	if(!panel) return;  @@ -506,19 +364,29 @@ void LLLandmarksPanel::updateSortOrder(LLInventoryPanel* panel, bool byDate)  	}  } +void LLLandmarksPanel::resetSelection() +{ +} +  // virtual  void LLLandmarksPanel::processParcelInfo(const LLParcelData& parcel_data)  {  	//this function will be called after user will try to create a pick for selected landmark.  	// We have to make request to sever to get parcel_id and snaption_id.  -	if(isLandmarkSelected()) +	if(mCreatePickItemId.notNull())  	{ -		LLFolderViewModelItemInventory* cur_item = getCurSelectedViewModelItem(); -		if (!cur_item) return; -		LLUUID id = cur_item->getUUID(); -		LLInventoryItem* inv_item = mCurrentSelectedList->getModel()->getItem(id); -		doActionOnCurSelectedLandmark(boost::bind( -				&LLLandmarksPanel::doProcessParcelInfo, this, _1, getCurSelectedItem(), inv_item, parcel_data)); +		LLInventoryItem* inv_item = gInventory.getItem(mCreatePickItemId); + +        if (inv_item && inv_item->getInventoryType() == LLInventoryType::IT_LANDMARK) +        { +            // we are processing response for doCreatePick, landmark should be already loaded +            LLLandmark* landmark = LLLandmarkActions::getLandmark(inv_item->getUUID()); +            if (landmark) +            { +                doProcessParcelInfo(landmark, inv_item, parcel_data); +            } +        } +        mCreatePickItemId.setNull();  	}  } @@ -543,16 +411,6 @@ void LLLandmarksPanel::setErrorStatus(S32 status, const std::string& reason)  // PRIVATE METHODS  ////////////////////////////////////////////////////////////////////////// -void LLLandmarksPanel::initFavoritesInventoryPanel() -{ -	mFavoritesInventoryPanel = getChild<LLPlacesInventoryPanel>("favorites_list"); - -	initLandmarksPanel(mFavoritesInventoryPanel); -	mFavoritesInventoryPanel->getFilter().setEmptyLookupMessage("FavoritesNoMatchingItems"); - -	initAccordion("tab_favorites", mFavoritesInventoryPanel, true); -} -  void LLLandmarksPanel::initLandmarksInventoryPanel()  {  	mLandmarksInventoryPanel = getChild<LLPlacesInventoryPanel>("landmarks_list"); @@ -564,40 +422,14 @@ void LLLandmarksPanel::initLandmarksInventoryPanel()  	// subscribe to have auto-rename functionality while creating New Folder  	mLandmarksInventoryPanel->setSelectCallback(boost::bind(&LLInventoryPanel::onSelectionChange, mLandmarksInventoryPanel, _1, _2)); -	mMyLandmarksAccordionTab = initAccordion("tab_landmarks", mLandmarksInventoryPanel, true); -} - -void LLLandmarksPanel::initMyInventoryPanel() -{ -	mMyInventoryPanel= getChild<LLPlacesInventoryPanel>("my_inventory_list"); - -	initLandmarksPanel(mMyInventoryPanel); - -	initAccordion("tab_inventory", mMyInventoryPanel, false); -} - -void LLLandmarksPanel::initLibraryInventoryPanel() -{ -	mLibraryInventoryPanel = getChild<LLPlacesInventoryPanel>("library_list"); - -	initLandmarksPanel(mLibraryInventoryPanel); - -	// We want to fetch only "Landmarks" category from the library. -	const LLUUID &landmarks_cat = gInventory.findLibraryCategoryUUIDForType(LLFolderType::FT_LANDMARK, false); -	if (landmarks_cat.notNull()) -	{ -		LLInventoryModelBackgroundFetch::instance().start(landmarks_cat); -	} - -	// Expanding "Library" tab for new users who have no landmarks in "My Inventory". -	initAccordion("tab_library", mLibraryInventoryPanel, true); +	mCurrentSelectedList = mLandmarksInventoryPanel;  }  void LLLandmarksPanel::initLandmarksPanel(LLPlacesInventoryPanel* inventory_list)  {  	inventory_list->getFilter().setEmptyLookupMessage("PlacesNoMatchingItems");  	inventory_list->setFilterTypes(0x1 << LLInventoryType::IT_LANDMARK); -	inventory_list->setSelectCallback(boost::bind(&LLLandmarksPanel::onSelectionChange, this, inventory_list, _1, _2)); +	inventory_list->setSelectCallback(boost::bind(&LLLandmarksPanel::updateVerbs, this));  	inventory_list->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);  	bool sorting_order = gSavedSettings.getBOOL("LandmarksSortedByDate"); @@ -615,86 +447,10 @@ void LLLandmarksPanel::initLandmarksPanel(LLPlacesInventoryPanel* inventory_list  	inventory_list->saveFolderState();  } -LLAccordionCtrlTab* LLLandmarksPanel::initAccordion(const std::string& accordion_tab_name, LLPlacesInventoryPanel* inventory_list,	bool expand_tab) -{ -	LLAccordionCtrlTab* accordion_tab = getChild<LLAccordionCtrlTab>(accordion_tab_name); - -	mAccordionTabs.push_back(accordion_tab); -	accordion_tab->setDropDownStateChangedCallback( -		boost::bind(&LLLandmarksPanel::onAccordionExpandedCollapsed, this, _2, inventory_list)); -	accordion_tab->setDisplayChildren(expand_tab); -	return accordion_tab; -} - -void LLLandmarksPanel::onAccordionExpandedCollapsed(const LLSD& param, LLPlacesInventoryPanel* inventory_list) -{ -	bool expanded = param.asBoolean(); - -	if(!expanded && (mCurrentSelectedList == inventory_list)) -	{ -		inventory_list->getRootFolder()->clearSelection(); - -		mCurrentSelectedList = NULL; -		updateVerbs(); -	} - -	// Start background fetch, mostly for My Inventory and Library -	if (expanded) -	{ -		const LLUUID &cat_id = inventory_list->getRootFolderID(); -		// Just because the category itself has been fetched, doesn't mean its child folders have. -		/* -		  if (!gInventory.isCategoryComplete(cat_id)) -		*/ -		{ -			LLInventoryModelBackgroundFetch::instance().start(cat_id); -		} - -		// Apply filter substring because it might have been changed -		// while accordion was closed. See EXT-3714. -		filter_list(inventory_list, sFilterSubString); -	} -} - -void LLLandmarksPanel::deselectOtherThan(const LLPlacesInventoryPanel* inventory_list) -{ -	if (inventory_list != mFavoritesInventoryPanel) -	{ -		mFavoritesInventoryPanel->clearSelection(); -	} - -	if (inventory_list != mLandmarksInventoryPanel) -	{ -		mLandmarksInventoryPanel->clearSelection(); -	} -	if (inventory_list != mMyInventoryPanel) -	{ -		mMyInventoryPanel->clearSelection(); -	} -	if (inventory_list != mLibraryInventoryPanel) -	{ -		mLibraryInventoryPanel->clearSelection(); -	} -}  // List Commands Handlers  void LLLandmarksPanel::initListCommandsHandlers()  { -	mListCommands = getChild<LLPanel>("bottom_panel"); - -	mGearButton = getChild<LLMenuButton>(OPTIONS_BUTTON_NAME); -	mGearButton->setMouseDownCallback(boost::bind(&LLLandmarksPanel::onActionsButtonClick, this)); - -	mListCommands->childSetAction(TRASH_BUTTON_NAME, boost::bind(&LLLandmarksPanel::onTrashButtonClick, this)); - -	LLDragAndDropButton* trash_btn = mListCommands->getChild<LLDragAndDropButton>(TRASH_BUTTON_NAME); -	trash_btn->setDragAndDropHandler(boost::bind(&LLLandmarksPanel::handleDragAndDropToTrash, this -			,	_4 // BOOL drop -			,	_5 // EDragAndDropType cargo_type -			,	_6 // void* cargo_data -			,	_7 // EAcceptance* accept -			)); -  	mCommitCallbackRegistrar.add("Places.LandmarksGear.Add.Action", boost::bind(&LLLandmarksPanel::onAddAction, this, _2));  	mCommitCallbackRegistrar.add("Places.LandmarksGear.CopyPaste.Action", boost::bind(&LLLandmarksPanel::onClipboardAction, this, _2));  	mCommitCallbackRegistrar.add("Places.LandmarksGear.Custom.Action", boost::bind(&LLLandmarksPanel::onCustomAction, this, _2)); @@ -703,23 +459,16 @@ void LLLandmarksPanel::initListCommandsHandlers()  	mEnableCallbackRegistrar.add("Places.LandmarksGear.Enable", boost::bind(&LLLandmarksPanel::isActionEnabled, this, _2));  	mGearLandmarkMenu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_places_gear_landmark.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());  	mGearFolderMenu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_places_gear_folder.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); -	mMenuAdd = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_place_add_button.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); +	mSortingMenu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_places_gear_sorting.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); +	mAddMenu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_place_add_button.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());  	mGearLandmarkMenu->setVisibilityChangeCallback(boost::bind(&LLLandmarksPanel::onMenuVisibilityChange, this, _1, _2));  	mGearFolderMenu->setVisibilityChangeCallback(boost::bind(&LLLandmarksPanel::onMenuVisibilityChange, this, _1, _2)); -	mListCommands->childSetAction(ADD_BUTTON_NAME, boost::bind(&LLLandmarksPanel::showActionMenu, this, mMenuAdd, ADD_BUTTON_NAME)); -} - - -void LLLandmarksPanel::updateListCommands() -{ -	bool add_folder_enabled = isActionEnabled("category"); -	bool trash_enabled = isActionEnabled("delete") && (isFolderSelected() || isLandmarkSelected()); - -	// keep Options & Add Landmark buttons always enabled -	mListCommands->getChildView(ADD_FOLDER_BUTTON_NAME)->setEnabled(add_folder_enabled); -	mListCommands->getChildView(TRASH_BUTTON_NAME)->setEnabled(trash_enabled); +	// show menus even if all items are disabled +	mGearLandmarkMenu->setAlwaysShowMenu(TRUE); +	mGearFolderMenu->setAlwaysShowMenu(TRUE); +	mAddMenu->setAlwaysShowMenu(TRUE);  }  void LLLandmarksPanel::updateMenuVisibility(LLUICtrl* menu) @@ -727,43 +476,6 @@ void LLLandmarksPanel::updateMenuVisibility(LLUICtrl* menu)  	onMenuVisibilityChange(menu, LLSD().with("visibility", true));  } -void LLLandmarksPanel::onActionsButtonClick() -{ -	LLToggleableMenu* menu = mGearFolderMenu; - -	if(mCurrentSelectedList) -	{ -		LLFolderViewModelItemInventory* listenerp = getCurSelectedViewModelItem(); -		if(!listenerp) -			return; - -		if (listenerp->getInventoryType() == LLInventoryType::IT_LANDMARK) -		{ -			menu = mGearLandmarkMenu; -		} -	} - -	mGearButton->setMenu(menu); -} - -void LLLandmarksPanel::showActionMenu(LLMenuGL* menu, std::string spawning_view_name) -{ -	if (menu) -	{ -		menu->buildDrawLabels(); -		menu->updateParent(LLMenuGL::sMenuContainer); -		menu->arrangeAndClear(); - -		LLView* spawning_view = getChild<LLView>(spawning_view_name); - -		S32 menu_x, menu_y; -		//show menu in co-ordinates of panel -		spawning_view->localPointToOtherView(0, spawning_view->getRect().getHeight(), &menu_x, &menu_y, this); -		menu_y += menu->getRect().getHeight(); -		LLMenuGL::showPopup(this, menu, menu_x, menu_y); -	} -} -  void LLLandmarksPanel::onTrashButtonClick() const  {  	onClipboardAction("delete"); @@ -775,7 +487,8 @@ void LLLandmarksPanel::onAddAction(const LLSD& userdata) const  	LLFolderViewItem* item = getCurSelectedItem();  	std::string command_name = userdata.asString(); -	if("add_landmark" == command_name) +	if("add_landmark" == command_name +        || "add_landmark_root" == command_name)  	{  		LLViewerInventoryItem* landmark = LLLandmarkActions::findLandmarkForAgentPos();  		if(landmark) @@ -784,7 +497,20 @@ void LLLandmarksPanel::onAddAction(const LLSD& userdata) const  		}  		else  		{ -			LLFloaterSidePanelContainer::showPanel("places", LLSD().with("type", "create_landmark")); +            LLSD args; +            args["type"] = "create_landmark"; +            if ("add_landmark" == command_name +                && view_model->getInventoryType() == LLInventoryType::IT_CATEGORY) +            { +                args["dest_folder"] = view_model->getUUID(); +            } +            if ("add_landmark_root" == command_name +                && mCurrentSelectedList == mLandmarksInventoryPanel) +            { +                args["dest_folder"] = mLandmarksInventoryPanel->getRootFolderID(); +            } +            // else will end up in favorites +			LLFloaterReg::showInstance("add_landmark", args);  		}  	}   	else if ("category" == command_name) @@ -816,13 +542,14 @@ void LLLandmarksPanel::onAddAction(const LLSD& userdata) const  			//in case My Landmarks tab is completely empty (thus cannot be determined as being selected)  			menu_create_inventory_item(mLandmarksInventoryPanel, NULL,  LLSD("category"),   				gInventory.findCategoryUUIDForType(LLFolderType::FT_LANDMARK)); - -			if (mMyLandmarksAccordionTab) -			{ -				mMyLandmarksAccordionTab->changeOpenClose(false); -			}  		}  	} +    else if ("category_root" == command_name) +    { +        //in case My Landmarks tab is completely empty (thus cannot be determined as being selected) +        menu_create_inventory_item(mLandmarksInventoryPanel, NULL, LLSD("category"), +            gInventory.findCategoryUUIDForType(LLFolderType::FT_LANDMARK)); +    }  }  void LLLandmarksPanel::onClipboardAction(const LLSD& userdata) const @@ -856,27 +583,11 @@ void LLLandmarksPanel::onFoldingAction(const LLSD& userdata)  	if ("expand_all" == command_name)  	{ -		expand_all_folders(mFavoritesInventoryPanel->getRootFolder()); -		expand_all_folders(mLandmarksInventoryPanel->getRootFolder()); -		expand_all_folders(mMyInventoryPanel->getRootFolder()); -		expand_all_folders(mLibraryInventoryPanel->getRootFolder()); - -		for (accordion_tabs_t::const_iterator iter = mAccordionTabs.begin(); iter != mAccordionTabs.end(); ++iter) -		{ -			(*iter)->changeOpenClose(false); -		} +		expand_all_folders(mCurrentSelectedList->getRootFolder());  	}  	else if ("collapse_all" == command_name)  	{ -		collapse_all_folders(mFavoritesInventoryPanel->getRootFolder()); -		collapse_all_folders(mLandmarksInventoryPanel->getRootFolder()); -		collapse_all_folders(mMyInventoryPanel->getRootFolder()); -		collapse_all_folders(mLibraryInventoryPanel->getRootFolder()); - -		for (accordion_tabs_t::const_iterator iter = mAccordionTabs.begin(); iter != mAccordionTabs.end(); ++iter) -		{ -			(*iter)->changeOpenClose(true); -		} +		collapse_all_folders(mCurrentSelectedList->getRootFolder());  	}  	else if ("sort_by_date" == command_name)  	{ @@ -884,8 +595,6 @@ void LLLandmarksPanel::onFoldingAction(const LLSD& userdata)  		sorting_order=!sorting_order;  		gSavedSettings.setBOOL("LandmarksSortedByDate",sorting_order);  		updateSortOrder(mLandmarksInventoryPanel, sorting_order); -		updateSortOrder(mMyInventoryPanel, sorting_order); -		updateSortOrder(mLibraryInventoryPanel, sorting_order);  	}  	else  	{ @@ -917,51 +626,21 @@ bool LLLandmarksPanel::isActionEnabled(const LLSD& userdata) const  		? mCurrentSelectedList->getRootFolder()   		: NULL; +	bool is_single_selection = root_folder_view && root_folder_view->getSelectedCount() == 1; +  	if ("collapse_all" == command_name)  	{ -		bool disable_collapse_all =	!has_expanded_folders(mFavoritesInventoryPanel->getRootFolder()) -									&& !has_expanded_folders(mLandmarksInventoryPanel->getRootFolder()) -									&& !has_expanded_folders(mMyInventoryPanel->getRootFolder()) -									&& !has_expanded_folders(mLibraryInventoryPanel->getRootFolder()); -		if (disable_collapse_all) -		{ -			for (accordion_tabs_t::const_iterator iter = mAccordionTabs.begin(); iter != mAccordionTabs.end(); ++iter) -			{ -				if ((*iter)->isExpanded()) -				{ -					disable_collapse_all = false; -					break; -				} -			} -		} - -		return !disable_collapse_all; +		return has_expanded_folders(mCurrentSelectedList->getRootFolder());  	}  	else if ("expand_all" == command_name)  	{ -		bool disable_expand_all = !has_collapsed_folders(mFavoritesInventoryPanel->getRootFolder()) -								  && !has_collapsed_folders(mLandmarksInventoryPanel->getRootFolder()) -								  && !has_collapsed_folders(mMyInventoryPanel->getRootFolder()) -								  && !has_collapsed_folders(mLibraryInventoryPanel->getRootFolder()); -		if (disable_expand_all) -		{ -			for (accordion_tabs_t::const_iterator iter = mAccordionTabs.begin(); iter != mAccordionTabs.end(); ++iter) -			{ -				if (!(*iter)->isExpanded()) -				{ -					disable_expand_all = false; -					break; -				} -			} -		} - -		return !disable_expand_all; +		return has_collapsed_folders(mCurrentSelectedList->getRootFolder());  	}  	else if ("sort_by_date"	== command_name)  	{ -		// disable "sort_by_date" for Favorites accordion because +		// disable "sort_by_date" for Favorites tab because  		// it has its own items order. EXT-1758 -		if (mCurrentSelectedList == mFavoritesInventoryPanel) +		if (!isLandmarksPanel)  		{  			return false;  		} @@ -978,6 +657,11 @@ bool LLLandmarksPanel::isActionEnabled(const LLSD& userdata) const  		std::set<LLFolderViewItem*> selected_uuids =    root_folder_view->getSelectionList(); +		if (selected_uuids.empty()) +		{ +			return false; +		} +		  		// Allow to execute the command only if it can be applied to all selected items.  		for (std::set<LLFolderViewItem*>::const_iterator iter =    selected_uuids.begin(); iter != selected_uuids.end(); ++iter)  		{ @@ -998,7 +682,6 @@ bool LLLandmarksPanel::isActionEnabled(const LLSD& userdata) const  			)  	{  		// disable some commands for multi-selection. EXT-1757 -		bool is_single_selection = root_folder_view && root_folder_view->getSelectedCount() == 1;  		if (!is_single_selection)  		{  			return false; @@ -1017,9 +700,9 @@ bool LLLandmarksPanel::isActionEnabled(const LLSD& userdata) const  			// Disable "Show on Map" if landmark loading is in progress.  			return !gLandmarkList.isAssetInLoadedCallbackMap(asset_uuid); -	} -	else if ("rename" == command_name) -	{ +		} +		else if ("rename" == command_name) +		{  			LLFolderViewItem* selected_item = getCurSelectedItem();  			if (!selected_item) return false; @@ -1028,16 +711,10 @@ bool LLLandmarksPanel::isActionEnabled(const LLSD& userdata) const  		return true;  	} -	else if("category" == command_name) -	{ -		// we can add folder only in Landmarks Accordion -		if (mCurrentSelectedList == mLandmarksInventoryPanel) -		{ -			// ... but except Received folder -			return !isReceivedFolderSelected(); -		} -		//"Add a folder" is enabled by default (case when My Landmarks is empty) -		else return true; +    if ("category_root" == command_name || "category" == command_name) +    { +		// we can add folder only in Landmarks tab +		return isLandmarksPanel;  	}  	else if("create_pick" == command_name)  	{ @@ -1051,6 +728,78 @@ bool LLLandmarksPanel::isActionEnabled(const LLSD& userdata) const  		}  		return false;  	} +    else if ("add_landmark" == command_name) +    { +        if (!is_single_selection) +        { +            return false; +        } + +        LLFolderViewModelItemInventory* view_model = getCurSelectedViewModelItem(); +        if (!view_model || view_model->getInventoryType() != LLInventoryType::IT_CATEGORY) +        { +            return false; +        } +        LLViewerInventoryItem* landmark = LLLandmarkActions::findLandmarkForAgentPos(); +        if (landmark) +        { +            //already exists +            return false; +        } +        return true; +    } +    else if ("add_landmark_root" == command_name) +    { +        LLViewerInventoryItem* landmark = LLLandmarkActions::findLandmarkForAgentPos(); +        if (landmark) +        { +            //already exists +            return false; +        } +        return true; +    } +    else if ("share" == command_name) +    { +        if (!mCurrentSelectedList) +        { +            return false; +        } +        if (!LLAvatarActions::canShareSelectedItems(mCurrentSelectedList)) +        { +            return false; +        } +        return true; +    } +	else if (command_name == "move_to_landmarks" || command_name == "move_to_favorites") +	{ +		LLFolderViewModelItemInventory* cur_item_model = getCurSelectedViewModelItem(); +		if (cur_item_model) +		{ +			LLFolderType::EType folder_type = command_name == "move_to_landmarks" ? LLFolderType::FT_FAVORITE : LLFolderType::FT_LANDMARK; +			if (!gInventory.isObjectDescendentOf(cur_item_model->getUUID(), gInventory.findCategoryUUIDForType(folder_type))) +			{ +				return false; +			} + +			if (root_folder_view) +			{ +				std::set<LLFolderViewItem*> selected_uuids = root_folder_view->getSelectionList(); +				for (std::set<LLFolderViewItem*>::const_iterator iter = selected_uuids.begin(); iter != selected_uuids.end(); ++iter) +				{ +					LLFolderViewItem* item = *iter; +					if (!item) return false; + +					cur_item_model = static_cast<LLFolderViewModelItemInventory*>(item->getViewModelItem()); +					if (!cur_item_model || cur_item_model->getInventoryType() != LLInventoryType::IT_LANDMARK) +					{ +						return false; +					} +				} +				return true; +			} +		} +		return false; +	}  	else  	{  		LL_WARNS() << "Unprocessed command has come: " << command_name << LL_ENDL; @@ -1076,12 +825,42 @@ void LLLandmarksPanel::onCustomAction(const LLSD& userdata)  	}  	else if ("create_pick" == command_name)  	{ -		doActionOnCurSelectedLandmark(boost::bind(&LLLandmarksPanel::doCreatePick, this, _1)); +        LLFolderViewModelItemInventory* cur_item = getCurSelectedViewModelItem(); +        if (cur_item) +        { +            doActionOnCurSelectedLandmark(boost::bind(&LLLandmarksPanel::doCreatePick, this, _1, cur_item->getUUID())); +        }  	} +    else if ("share" == command_name && mCurrentSelectedList) +    { +        LLAvatarActions::shareWithAvatars(mCurrentSelectedList); +    }  	else if ("restore" == command_name && mCurrentSelectedList)  	{  		mCurrentSelectedList->doToSelected(userdata);  	} +	else if (command_name == "move_to_landmarks" || command_name == "move_to_favorites") +	{ +		LLFolderView* root_folder_view = mCurrentSelectedList ? mCurrentSelectedList->getRootFolder() : NULL; +		if (root_folder_view) +		{ +			LLFolderType::EType folder_type = command_name == "move_to_landmarks" ? LLFolderType::FT_LANDMARK : LLFolderType::FT_FAVORITE; +			std::set<LLFolderViewItem*> selected_uuids = root_folder_view->getSelectionList(); +			for (std::set<LLFolderViewItem*>::const_iterator iter = selected_uuids.begin(); iter != selected_uuids.end(); ++iter) +			{ +				LLFolderViewItem* item = *iter; +				if (item) +				{ +					LLFolderViewModelItemInventory* item_model = static_cast<LLFolderViewModelItemInventory*>(item->getViewModelItem()); +					if (item_model) +					{ +						change_item_parent(item_model->getUUID(), gInventory.findCategoryUUIDForType(folder_type)); +					} +				} +			} +		} + +	}  }  void LLLandmarksPanel::onMenuVisibilityChange(LLUICtrl* ctrl, const LLSD& param) @@ -1148,29 +927,17 @@ bool LLLandmarksPanel::canItemBeModified(const std::string& command_name, LLFold  	if (!item) return false; -	// nothing can be modified in Library -	if (mLibraryInventoryPanel == mCurrentSelectedList) return false; -  	bool can_be_modified = false;  	// landmarks can be modified in any other accordion...  	if (static_cast<LLFolderViewModelItemInventory*>(item->getViewModelItem())->getInventoryType() == LLInventoryType::IT_LANDMARK)  	{  		can_be_modified = true; - -		// we can modify landmarks anywhere except paste to My Inventory -		if ("paste" == command_name) -		{ -			can_be_modified = (mCurrentSelectedList != mMyInventoryPanel); -		}  	}  	else  	{  		// ...folders only in the Landmarks accordion... -		can_be_modified = mLandmarksInventoryPanel == mCurrentSelectedList; - -		// ...except "Received" folder -		can_be_modified &= !isReceivedFolderSelected(); +		can_be_modified = isLandmarksPanel;  	}  	// then ask LLFolderView permissions @@ -1287,12 +1054,10 @@ void LLLandmarksPanel::doShowOnMap(LLLandmark* landmark)  		LLFloaterReg::showInstance("world_map", "center");  	} -	mShowOnMapBtn->setEnabled(TRUE);  	mGearLandmarkMenu->setItemEnabled("show_on_map", TRUE);  }  void LLLandmarksPanel::doProcessParcelInfo(LLLandmark* landmark, -										   LLFolderViewItem* cur_item,  										   LLInventoryItem* inv_item,  										   const LLParcelData& parcel_data)  { @@ -1321,7 +1086,7 @@ void LLLandmarksPanel::doProcessParcelInfo(LLLandmark* landmark,  	LLPickData data;  	data.pos_global = landmark_global_pos; -	data.name = cur_item->getName(); +	data.name = inv_item->getName();  	data.desc = inv_item->getDescription();  	data.snapshot_id = parcel_data.snapshot_id;  	data.parcel_id = parcel_data.parcel_id; @@ -1341,11 +1106,13 @@ void LLLandmarksPanel::doProcessParcelInfo(LLLandmark* landmark,  					panel_pick, panel_places,params));  } -void LLLandmarksPanel::doCreatePick(LLLandmark* landmark) +void LLLandmarksPanel::doCreatePick(LLLandmark* landmark, const LLUUID &item_id)  {  	LLViewerRegion* region = gAgent.getRegion();  	if (!region) return; +    mCreatePickItemId = item_id; +  	LLGlobalVec pos_global;  	LLUUID region_id;  	landmark->getGlobalPos(pos_global); @@ -1398,27 +1165,12 @@ static void filter_list(LLPlacesInventoryPanel* inventory_list, const std::strin  	inventory_list->setFilterSubString(string);  } -static bool category_has_descendents(LLPlacesInventoryPanel* inventory_list) -{ -	LLViewerInventoryCategory* category = gInventory.getCategory(inventory_list->getRootFolderID()); -	if (category) -	{ -		return category->getDescendentCount() > 0; -	} - -	return false; -} -  static void collapse_all_folders(LLFolderView* root_folder)  {  	if (!root_folder)  		return;  	root_folder->setOpenArrangeRecursively(FALSE, LLFolderViewFolder::RECURSE_DOWN); - -	// The top level folder is invisible, it must be open to -	// display its sub-folders. -	root_folder->openTopLevelFolders();  	root_folder->arrangeAll();  } @@ -1485,4 +1237,31 @@ void toggle_restore_menu(LLMenuGL *menu, BOOL visible, BOOL enabled)  		}  	}  } + +LLFavoritesPanel::LLFavoritesPanel() +	:	LLLandmarksPanel(false) +{ +	buildFromFile("panel_favorites.xml"); +} + +BOOL LLFavoritesPanel::postBuild() +{ +	if (!gInventory.isInventoryUsable()) +		return FALSE; + +	// mast be called before any other initXXX methods to init Gear menu +	LLLandmarksPanel::initListCommandsHandlers(); + +	initFavoritesInventoryPanel(); + +	return TRUE; +} + +void LLFavoritesPanel::initFavoritesInventoryPanel() +{ +	mCurrentSelectedList = getChild<LLPlacesInventoryPanel>("favorites_list"); + +	LLLandmarksPanel::initLandmarksPanel(mCurrentSelectedList); +	mCurrentSelectedList->getFilter().setEmptyLookupMessage("FavoritesNoMatchingItems"); +}  // EOF diff --git a/indra/newview/llpanellandmarks.h b/indra/newview/llpanellandmarks.h index c11cbe05ae..d7408269b5 100644 --- a/indra/newview/llpanellandmarks.h +++ b/indra/newview/llpanellandmarks.h @@ -50,81 +50,69 @@ class LLLandmarksPanel : public LLPanelPlacesTab, LLRemoteParcelInfoObserver  {  public:  	LLLandmarksPanel(); +	LLLandmarksPanel(bool is_landmark_panel);  	virtual ~LLLandmarksPanel(); -	/*virtual*/ BOOL postBuild(); -	/*virtual*/ void onSearchEdit(const std::string& string); -	/*virtual*/ void onShowOnMap(); -	/*virtual*/ void onShowProfile(); -	/*virtual*/ void onTeleport(); -	/*virtual*/ void updateVerbs(); -	/*virtual*/ bool isSingleItemSelected(); +	BOOL postBuild() override; +	void onSearchEdit(const std::string& string) override; +	void onShowOnMap() override; +	void onShowProfile() override; +	void onTeleport() override; +	void onRemoveSelected() override; +	void updateVerbs() override; +	bool isSingleItemSelected() override; + +    LLToggleableMenu* getSelectionMenu() override; +    LLToggleableMenu* getSortingMenu() override; +    LLToggleableMenu* getCreateMenu() override; + +    /** +     * Processes drag-n-drop of the Landmarks and folders into trash button. +     */ +    bool handleDragAndDropToTrash(BOOL drop, EDragAndDropType cargo_type, void* cargo_data, EAcceptance* accept) override; -	void onSelectionChange(LLPlacesInventoryPanel* inventory_list, const std::deque<LLFolderViewItem*> &items, BOOL user_action); -	void onSelectorButtonClicked();  	void setCurrentSelectedList(LLPlacesInventoryPanel* inventory_list)  	{  		mCurrentSelectedList = inventory_list;  	}  	/** -	 * 	Update filter ShowFolderState setting to show empty folder message -	 *  if Landmarks inventory folder is empty. -	 */ -	void updateShowFolderState(); - -	/**  	 * Selects item with "obj_id" in one of accordion tabs.  	 */  	void setItemSelected(const LLUUID& obj_id, BOOL take_keyboard_focus); -	LLPlacesInventoryPanel* getLibraryInventoryPanel() { return mLibraryInventoryPanel; } -  	void updateMenuVisibility(LLUICtrl* menu); +	void doCreatePick(LLLandmark* landmark, const LLUUID &item_id ); + +	void resetSelection(); +  protected:  	/**  	 * @return true - if current selected panel is not null and selected item is a landmark  	 */  	bool isLandmarkSelected() const;  	bool isFolderSelected() const; -	bool isReceivedFolderSelected() const;  	void doActionOnCurSelectedLandmark(LLLandmarkList::loaded_callback_t cb);  	LLFolderViewItem* getCurSelectedItem() const;  	LLFolderViewModelItemInventory* getCurSelectedViewModelItem() const; -	/** -	 * Selects item with "obj_id" in "inventory_list" and scrolls accordion -	 * scrollbar to show the item. -	 * Returns pointer to the item if it is found in "inventory_list", otherwise NULL. -	 */ -	LLFolderViewItem* selectItemInAccordionTab(LLPlacesInventoryPanel* inventory_list, -											   const std::string& tab_name, -											   const LLUUID& obj_id, -											   BOOL take_keyboard_focus) const; -  	void updateSortOrder(LLInventoryPanel* panel, bool byDate);  	//LLRemoteParcelInfoObserver interface -	/*virtual*/ void processParcelInfo(const LLParcelData& parcel_data); -	/*virtual*/ void setParcelID(const LLUUID& parcel_id); -	/*virtual*/ void setErrorStatus(S32 status, const std::string& reason); +	void processParcelInfo(const LLParcelData& parcel_data) override; +	void setParcelID(const LLUUID& parcel_id) override; +	void setErrorStatus(S32 status, const std::string& reason) override; + +	// List Commands Handlers +	void initListCommandsHandlers(); +	void initLandmarksPanel(LLPlacesInventoryPanel* inventory_list); + +	LLPlacesInventoryPanel*		mCurrentSelectedList;  private: -	void initFavoritesInventoryPanel();  	void initLandmarksInventoryPanel(); -	void initMyInventoryPanel(); -	void initLibraryInventoryPanel(); -	void initLandmarksPanel(LLPlacesInventoryPanel* inventory_list); -	LLAccordionCtrlTab* initAccordion(const std::string& accordion_tab_name, LLPlacesInventoryPanel* inventory_list, bool expand_tab); -	void onAccordionExpandedCollapsed(const LLSD& param, LLPlacesInventoryPanel* inventory_list); -	void deselectOtherThan(const LLPlacesInventoryPanel* inventory_list); -	// List Commands Handlers -	void initListCommandsHandlers(); -	void updateListCommands(); -	void onActionsButtonClick(); -	void showActionMenu(LLMenuGL* menu, std::string spawning_view_name);  	void onTrashButtonClick() const;  	void onAddAction(const LLSD& command_name) const;  	void onClipboardAction(const LLSD& command_name) const; @@ -151,38 +139,33 @@ private:  	void onPickPanelExit( LLPanelPickEdit* pick_panel, LLView* owner, const LLSD& params);  	/** -	 * Processes drag-n-drop of the Landmarks and folders into trash button. -	 */ -	bool handleDragAndDropToTrash(BOOL drop, EDragAndDropType cargo_type, void* cargo_data, EAcceptance* accept); - -	/**  	 * Landmark actions callbacks. Fire when a landmark is loaded from the list.  	 */  	void doShowOnMap(LLLandmark* landmark);  	void doProcessParcelInfo(LLLandmark* landmark, -							 LLFolderViewItem* cur_item,  							 LLInventoryItem* inv_item,  							 const LLParcelData& parcel_data); -	void doCreatePick(LLLandmark* landmark);  private: -	LLPlacesInventoryPanel*		mFavoritesInventoryPanel;  	LLPlacesInventoryPanel*		mLandmarksInventoryPanel; -	LLPlacesInventoryPanel*		mMyInventoryPanel; -	LLPlacesInventoryPanel*		mLibraryInventoryPanel; -	LLMenuButton*				mGearButton;  	LLToggleableMenu*			mGearLandmarkMenu;  	LLToggleableMenu*			mGearFolderMenu; -	LLMenuGL*					mMenuAdd; -	LLPlacesInventoryPanel*		mCurrentSelectedList; -	LLInventoryObserver*		mInventoryObserver; +	LLToggleableMenu*			mSortingMenu; +	LLToggleableMenu*			mAddMenu; -	LLPanel*					mListCommands; +	bool						isLandmarksPanel; -	typedef	std::vector<LLAccordionCtrlTab*> accordion_tabs_t; -	accordion_tabs_t			mAccordionTabs; +    LLUUID                      mCreatePickItemId; // item we requested a pick for +}; -	LLAccordionCtrlTab*			mMyLandmarksAccordionTab; + +class LLFavoritesPanel : public LLLandmarksPanel +{ +public: +	LLFavoritesPanel(); + +	BOOL postBuild() override; +	void initFavoritesInventoryPanel();  };  #endif //LL_LLPANELLANDMARKS_H diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp index 3964dc075c..381b80fb66 100644 --- a/indra/newview/llpanellogin.cpp +++ b/indra/newview/llpanellogin.cpp @@ -254,7 +254,7 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,  	LLLineEditor* password_edit(getChild<LLLineEditor>("password_edit"));  	password_edit->setKeystrokeCallback(onPassKey, this);  	// STEAM-14: When user presses Enter with this field in focus, initiate login -	password_edit->setCommitCallback(boost::bind(&LLPanelLogin::onClickConnect, this)); +	password_edit->setCommitCallback(boost::bind(&LLPanelLogin::onClickConnect, false));  	// change z sort of clickable text to be behind buttons  	sendChildToBack(getChildView("forgot_password_text")); @@ -265,7 +265,7 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,      {          LLComboBox* favorites_combo = getChild<LLComboBox>("start_location_combo");          updateLocationSelectorsVisibility(); // separate so that it can be called from preferences -        favorites_combo->setReturnCallback(boost::bind(&LLPanelLogin::onClickConnect, this)); +        favorites_combo->setReturnCallback(boost::bind(&LLPanelLogin::onClickConnect, false));          favorites_combo->setFocusLostCallback(boost::bind(&LLPanelLogin::onLocationSLURL, this));          LLComboBox* server_choice_combo = getChild<LLComboBox>("server_combo"); @@ -458,6 +458,9 @@ void LLPanelLogin::addFavoritesToStartLocation()  	if (combo->getValue().asString().empty())  	{  		combo->selectFirstItem(); +        // Value 'home' or 'last' should have been taken from NextLoginLocation +        // but NextLoginLocation was not set, so init it from combo explicitly +        onLocationSLURL();  	}  } @@ -1004,12 +1007,15 @@ void LLPanelLogin::handleMediaEvent(LLPluginClassMedia* /*self*/, EMediaEvent ev  // Protected methods  //---------------------------------------------------------------------------  // static -void LLPanelLogin::onClickConnect(void *) +void LLPanelLogin::onClickConnect(bool commit_fields)  {  	if (sInstance && sInstance->mCallback)  	{ -		// JC - Make sure the fields all get committed. -		sInstance->setFocus(FALSE); +		if (commit_fields) +		{ +			// JC - Make sure the fields all get committed. +			sInstance->setFocus(FALSE); +		}  		LLComboBox* combo = sInstance->getChild<LLComboBox>("server_combo");  		LLSD combo_val = combo->getSelectedValue(); @@ -1132,7 +1138,7 @@ void LLPanelLogin::onUserListCommit(void*)             }             else             { -               onClickConnect(NULL); +               onClickConnect();             }          }      } @@ -1364,6 +1370,7 @@ void LLPanelLogin::onSelectServer()  			{  				// the grid specified by the location is not this one, so clear the combo  				location_combo->setCurrentByIndex(0); // last location on the new grid +				onLocationSLURL();  			}  		}			  		break; diff --git a/indra/newview/llpanellogin.h b/indra/newview/llpanellogin.h index 788c269ffd..c5e6b41def 100644 --- a/indra/newview/llpanellogin.h +++ b/indra/newview/llpanellogin.h @@ -99,7 +99,7 @@ private:  	static void setFields(LLPointer<LLCredential> credential); -	static void onClickConnect(void*); +	static void onClickConnect(bool commit_fields = true);  	static void onClickNewAccount(void*);  	static void onClickVersion(void*);  	static void onClickForgotPassword(void*); diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp index fbc1b80857..e9c9c451a2 100644 --- a/indra/newview/llpanelmaininventory.cpp +++ b/indra/newview/llpanelmaininventory.cpp @@ -115,6 +115,7 @@ LLPanelMainInventory::LLPanelMainInventory(const LLPanel::Params& p)  	  mSavedFolderState(NULL),  	  mFilterText(""),  	  mMenuGearDefault(NULL), +	  mMenuVisibility(NULL),  	  mMenuAddHandle(),  	  mNeedUploadCost(true)  { @@ -219,6 +220,17 @@ BOOL LLPanelMainInventory::postBuild()  				recent_items_panel->setSortOrder(gSavedSettings.getU32(LLInventoryPanel::RECENTITEMS_SORT_ORDER));  			}  		} +		if(mActivePanel) +		{ +			if(savedFilterState.has(mActivePanel->getFilter().getName())) +			{ +				LLSD items = savedFilterState.get(mActivePanel->getFilter().getName()); +				LLInventoryFilter::Params p; +				LLParamSDParser parser; +				parser.readSD(items, p); +				mActivePanel->getFilter().setSearchVisibilityTypes(p); +			} +		}  	} @@ -229,6 +241,7 @@ BOOL LLPanelMainInventory::postBuild()  	}  	mGearMenuButton = getChild<LLMenuButton>("options_gear_btn"); +	mVisibilityMenuButton = getChild<LLMenuButton>("options_visibility_btn");  	initListCommandsHandlers(); @@ -254,6 +267,9 @@ BOOL LLPanelMainInventory::postBuild()  LLPanelMainInventory::~LLPanelMainInventory( void )  {  	// Save the filters state. +	// Some params types cannot be saved this way +	// for example, LLParamSDParser doesn't know about U64, +	// so some FilterOps params should be revised.  	LLSD filterRoot;  	LLInventoryPanel* all_items_panel = getChild<LLInventoryPanel>("All Items");  	if (all_items_panel) @@ -1165,6 +1181,10 @@ void LLPanelMainInventory::initListCommandsHandlers()  	LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_inventory_add.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());  	mMenuAddHandle = menu->getHandle(); +	mMenuVisibility = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_inventory_search_visibility.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); +	mVisibilityMenuButton->setMenu(mMenuVisibility); +	mVisibilityMenuButton->setMenuPosition(LLMenuButton::MP_BOTTOM_LEFT); +  	// Update the trash button when selected item(s) get worn or taken off.  	LLOutfitObserver::instance().addCOFChangedCallback(boost::bind(&LLPanelMainInventory::updateListCommands, this));  } @@ -1354,6 +1374,21 @@ void LLPanelMainInventory::onCustomAction(const LLSD& userdata)  		}  		LLFloaterReg::showInstance("linkreplace", params);  	} + +	if (command_name == "toggle_search_trash") +	{ +		mActivePanel->getFilter().toggleSearchVisibilityTrash(); +	} + +	if (command_name == "toggle_search_library") +	{ +		mActivePanel->getFilter().toggleSearchVisibilityLibrary(); +	} + +	if (command_name == "include_links") +	{ +		mActivePanel->getFilter().toggleSearchVisibilityLinks(); +	}		  }  void LLPanelMainInventory::onVisibilityChange( BOOL new_visibility ) @@ -1499,6 +1534,21 @@ BOOL LLPanelMainInventory::isActionChecked(const LLSD& userdata)  		return sort_order_mask & LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP;  	} +	if (command_name == "toggle_search_trash") +	{ +		return (mActivePanel->getFilter().getSearchVisibilityTypes() & LLInventoryFilter::VISIBILITY_TRASH) != 0; +	} + +	if (command_name == "toggle_search_library") +	{ +		return (mActivePanel->getFilter().getSearchVisibilityTypes() & LLInventoryFilter::VISIBILITY_LIBRARY) != 0; +	} + +	if (command_name == "include_links") +	{ +		return (mActivePanel->getFilter().getSearchVisibilityTypes() & LLInventoryFilter::VISIBILITY_LINKS) != 0;	 +	}	 +  	return FALSE;  } diff --git a/indra/newview/llpanelmaininventory.h b/indra/newview/llpanelmaininventory.h index a6bdee233d..dfb8db9d12 100644 --- a/indra/newview/llpanelmaininventory.h +++ b/indra/newview/llpanelmaininventory.h @@ -93,6 +93,8 @@ public:  	void toggleFindOptions(); +    void resetFilters(); +  protected:  	//  	// Misc functions @@ -117,7 +119,6 @@ protected:  	void doToSelected(const LLSD& userdata);  	void closeAllFolders();  	void doCreate(const LLSD& userdata); -	void resetFilters();  	void setSortBy(const LLSD& userdata);  	void saveTexture(const LLSD& userdata);  	bool isSaveTextureEnabled(const LLSD& userdata); @@ -169,7 +170,9 @@ protected:  private:  	LLDragAndDropButton*		mTrashButton;  	LLToggleableMenu*			mMenuGearDefault; +	LLToggleableMenu*			mMenuVisibility;  	LLMenuButton*				mGearMenuButton; +	LLMenuButton*				mVisibilityMenuButton;  	LLHandle<LLView>			mMenuAddHandle;  	bool						mNeedUploadCost; diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp index 28a020870f..5be9ab6095 100644 --- a/indra/newview/llpaneloutfitedit.cpp +++ b/indra/newview/llpaneloutfitedit.cpp @@ -58,7 +58,6 @@  #include "llmenubutton.h"  #include "llpaneloutfitsinventory.h"  #include "lluiconstants.h" -#include "llsaveoutfitcombobtn.h"  #include "llscrolllistctrl.h"  #include "lltextbox.h"  #include "lltoggleablemenu.h" @@ -80,6 +79,8 @@ const U64 ATTACHMENT_MASK = (1LL << LLInventoryType::IT_ATTACHMENT) | (1LL << LL  const U64 ALL_ITEMS_MASK = WEARABLE_MASK | ATTACHMENT_MASK;  static const std::string REVERT_BTN("revert_btn"); +static const std::string SAVE_AS_BTN("save_as_btn"); +static const std::string SAVE_BTN("save_btn");  /////////////////////////////////////////////////////////////////////////////// @@ -562,7 +563,8 @@ BOOL LLPanelOutfitEdit::postBuild()  	mGearMenu = LLPanelOutfitEditGearMenu::create();  	mGearMenuBtn->setMenu(mGearMenu); -	mSaveComboBtn.reset(new LLSaveOutfitComboBtn(this)); +	getChild<LLButton>(SAVE_BTN)->setCommitCallback(boost::bind(&LLPanelOutfitEdit::saveOutfit, this, false)); +	getChild<LLButton>(SAVE_AS_BTN)->setCommitCallback(boost::bind(&LLPanelOutfitEdit::saveOutfit, this, true));  	onOutfitChanging(gAgentWearables.isCOFChangeInProgress());  	return TRUE; @@ -1239,11 +1241,9 @@ void LLPanelOutfitEdit::updateVerbs()  	bool outfit_locked = LLAppearanceMgr::getInstance()->isOutfitLocked();  	bool has_baseoutfit = LLAppearanceMgr::getInstance()->getBaseOutfitUUID().notNull(); -	mSaveComboBtn->setSaveBtnEnabled(!outfit_locked && outfit_is_dirty); +	getChildView(SAVE_BTN)->setEnabled(!outfit_locked && outfit_is_dirty);  	getChildView(REVERT_BTN)->setEnabled(outfit_is_dirty && has_baseoutfit); -	mSaveComboBtn->setMenuItemEnabled("save_outfit", !outfit_locked && outfit_is_dirty); -  	mStatus->setText(outfit_is_dirty ? getString("unsaved_changes") : getString("now_editing"));  	updateCurrentOutfitName(); @@ -1429,4 +1429,13 @@ void LLPanelOutfitEdit::saveListSelection()  	}  } +void LLPanelOutfitEdit::saveOutfit(bool as_new) +{ +	LLPanelOutfitsInventory* panel_outfits_inventory = LLPanelOutfitsInventory::findInstance(); +	if (panel_outfits_inventory) +	{ +		panel_outfits_inventory->saveOutfit(as_new); +	} 	 +} +  // EOF diff --git a/indra/newview/llpaneloutfitedit.h b/indra/newview/llpaneloutfitedit.h index 3c6efac0e7..d0597fb72b 100644 --- a/indra/newview/llpaneloutfitedit.h +++ b/indra/newview/llpaneloutfitedit.h @@ -58,7 +58,6 @@ class LLMenuButton;  class LLMenuGL;  class LLFindNonLinksByMask;  class LLFindWearablesOfType; -class LLSaveOutfitComboBtn;  class LLWearableItemTypeNameComparator;  class LLPanelOutfitEdit : public LLPanel @@ -195,6 +194,7 @@ private:  	void getSelectedItemsUUID(uuid_vec_t& uuid_list);  	void getCurrentItemUUID(LLUUID& selected_id);  	void onCOFChanged(); +	void saveOutfit(bool as_new = false);  	/**  	 * Method preserves selection while switching between folder/list view modes @@ -237,7 +237,6 @@ private:  	LLToggleableMenu*	mGearMenu;  	LLToggleableMenu*	mAddWearablesGearMenu;  	bool				mInitialized; -	std::auto_ptr<LLSaveOutfitComboBtn> mSaveComboBtn;  	LLMenuButton*		mWearablesGearMenuBtn;  	LLMenuButton*		mGearMenuBtn; diff --git a/indra/newview/llpaneloutfitsinventory.cpp b/indra/newview/llpaneloutfitsinventory.cpp index 8fff52ca4e..531073526b 100644 --- a/indra/newview/llpaneloutfitsinventory.cpp +++ b/indra/newview/llpaneloutfitsinventory.cpp @@ -40,7 +40,6 @@  #include "lloutfitgallery.h"  #include "lloutfitslist.h"  #include "llpanelwearing.h" -#include "llsaveoutfitcombobtn.h"  #include "llsidepanelappearance.h"  #include "llviewercontrol.h"  #include "llviewerfoldertype.h" @@ -49,6 +48,9 @@ static const std::string OUTFITS_TAB_NAME = "outfitslist_tab";  static const std::string OUTFIT_GALLERY_TAB_NAME = "outfit_gallery_tab";  static const std::string COF_TAB_NAME = "cof_tab"; +static const std::string SAVE_AS_BTN("save_as_btn"); +static const std::string SAVE_BTN("save_btn"); +  static LLPanelInjector<LLPanelOutfitsInventory> t_inventory("panel_outfits_inventory");  LLPanelOutfitsInventory::LLPanelOutfitsInventory() : @@ -90,8 +92,9 @@ BOOL LLPanelOutfitsInventory::postBuild()  	{  		LLInventoryModelBackgroundFetch::instance().start(outfits_cat);  	} -	 -	mSaveComboBtn.reset(new LLSaveOutfitComboBtn(this, true)); + +	getChild<LLButton>(SAVE_BTN)->setCommitCallback(boost::bind(&LLPanelOutfitsInventory::saveOutfit, this, false)); +	getChild<LLButton>(SAVE_AS_BTN)->setCommitCallback(boost::bind(&LLPanelOutfitsInventory::saveOutfit, this, true));  	return TRUE;  } @@ -246,6 +249,12 @@ LLPanelOutfitsInventory* LLPanelOutfitsInventory::findInstance()  	return dynamic_cast<LLPanelOutfitsInventory*>(LLFloaterSidePanelContainer::getPanel("appearance", "panel_outfits_inventory"));  } +void LLPanelOutfitsInventory::openApearanceTab(const std::string& tab_name) +{ +    if (!mAppearanceTabs) return; +    mAppearanceTabs->selectTabByName(tab_name); +} +  //////////////////////////////////////////////////////////////////////////////////  // List Commands                                                                // @@ -269,7 +278,7 @@ void LLPanelOutfitsInventory::updateListCommands()  	mOutfitGalleryPanel->childSetEnabled("trash_btn", trash_enabled);  	wear_btn->setEnabled(wear_enabled);  	wear_btn->setVisible(wear_visible); -	mSaveComboBtn->setMenuItemEnabled("save_outfit", make_outfit_enabled); +	getChild<LLButton>(SAVE_BTN)->setEnabled(make_outfit_enabled);  	wear_btn->setToolTip(getString((!isOutfitsGalleryPanelActive() && mMyOutfitsPanel->hasItemSelected()) ? "wear_items_tooltip" : "wear_outfit_tooltip"));  } @@ -368,3 +377,15 @@ LLSidepanelAppearance* LLPanelOutfitsInventory::getAppearanceSP()  		dynamic_cast<LLSidepanelAppearance*>(LLFloaterSidePanelContainer::getPanel("appearance"));  	return panel_appearance;  } + +void LLPanelOutfitsInventory::saveOutfit(bool as_new) +{ +	if (!as_new && LLAppearanceMgr::getInstance()->updateBaseOutfit()) +	{ +		// we don't need to ask for an outfit name, and updateBaseOutfit() successfully saved. +		// If updateBaseOutfit fails, ask for an outfit name anyways +		return; +	} + +	onSave(); +} diff --git a/indra/newview/llpaneloutfitsinventory.h b/indra/newview/llpaneloutfitsinventory.h index 6a0ea04fa6..50d7074d4b 100644 --- a/indra/newview/llpaneloutfitsinventory.h +++ b/indra/newview/llpaneloutfitsinventory.h @@ -38,7 +38,6 @@ class LLPanelWearing;  class LLMenuGL;  class LLSidepanelAppearance;  class LLTabContainer; -class LLSaveOutfitComboBtn;  class LLPanelOutfitsInventory : public LLPanel  { @@ -52,6 +51,7 @@ public:  	void onSearchEdit(const std::string& string);  	void onSave(); +	void saveOutfit(bool as_new = false);  	bool onSaveCommit(const LLSD& notification, const LLSD& response); @@ -59,13 +59,14 @@ public:  	static LLPanelOutfitsInventory* findInstance(); +	void openApearanceTab(const std::string& tab_name); +  protected:  	void updateVerbs();  private:  	LLTabContainer*			mAppearanceTabs;  	std::string 			mFilterSubString; -	std::auto_ptr<LLSaveOutfitComboBtn> mSaveComboBtn;  	//////////////////////////////////////////////////////////////////////////////////  	// tab panels                                                                   // diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp index e5142f2b5f..5997d522c4 100644 --- a/indra/newview/llpanelpeople.cpp +++ b/indra/newview/llpanelpeople.cpp @@ -661,6 +661,7 @@ BOOL LLPanelPeople::postBuild()  	mRecentList->setShowIcons("RecentListShowIcons");  	mGroupList = getChild<LLGroupList>("group_list"); +	mGroupList->setNoItemsCommentText(getString("no_groups_msg"));  	mGroupList->setNoItemsMsg(getString("no_groups_msg"));  	mGroupList->setNoFilteredItemsMsg(getString("no_filtered_groups_msg")); diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp index 53870fb5c7..9c67ec40fe 100644 --- a/indra/newview/llpanelplaces.cpp +++ b/indra/newview/llpanelplaces.cpp @@ -53,6 +53,7 @@  #include "llagentpicksinfo.h"  #include "llavatarpropertiesprocessor.h"  #include "llcommandhandler.h" +#include "lldndbutton.h"  #include "llfloaterworldmap.h"  #include "llinventorybridge.h"  #include "llinventoryobserver.h" @@ -79,6 +80,7 @@  static const F32 PLACE_INFO_UPDATE_INTERVAL = 3.0;  static const std::string AGENT_INFO_TYPE			= "agent";  static const std::string CREATE_LANDMARK_INFO_TYPE	= "create_landmark"; +static const std::string CREATE_PICK_TYPE			= "create_pick";  static const std::string LANDMARK_INFO_TYPE			= "landmark";  static const std::string REMOTE_PLACE_INFO_TYPE		= "remote_place";  static const std::string TELEPORT_HISTORY_INFO_TYPE	= "teleport_history"; @@ -293,8 +295,25 @@ BOOL LLPanelPlaces::postBuild()  	mOverflowBtn = getChild<LLMenuButton>("overflow_btn");  	mOverflowBtn->setMouseDownCallback(boost::bind(&LLPanelPlaces::onOverflowButtonClicked, this)); -	mPlaceInfoBtn = getChild<LLButton>("profile_btn"); -	mPlaceInfoBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onProfileButtonClicked, this)); +    mGearMenuButton = getChild<LLMenuButton>("options_gear_btn"); +    mGearMenuButton->setMouseDownCallback(boost::bind(&LLPanelPlaces::onGearMenuClick, this)); + +    mSortingMenuButton = getChild<LLMenuButton>("sorting_menu_btn"); +    mSortingMenuButton->setMouseDownCallback(boost::bind(&LLPanelPlaces::onSortingMenuClick, this)); + +    mAddMenuButton = getChild<LLMenuButton>("add_menu_btn"); +    mAddMenuButton->setMouseDownCallback(boost::bind(&LLPanelPlaces::onAddMenuClick, this)); + +    mRemoveSelectedBtn = getChild<LLButton>("trash_btn"); +    mRemoveSelectedBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onRemoveButtonClicked, this)); + +    LLDragAndDropButton* trash_btn = (LLDragAndDropButton*)mRemoveSelectedBtn; +    trash_btn->setDragAndDropHandler(boost::bind(&LLPanelPlaces::handleDragAndDropToTrash, this +        , _4 // BOOL drop +        , _5 // EDragAndDropType cargo_type +        , _6 // void* cargo_data +        , _7 // EAcceptance* accept +    ));  	LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;  	registrar.add("Places.OverflowMenu.Action",  boost::bind(&LLPanelPlaces::onOverflowMenuItemClicked, this, _2)); @@ -323,6 +342,10 @@ BOOL LLPanelPlaces::postBuild()  		mTabContainer->setCommitCallback(boost::bind(&LLPanelPlaces::onTabSelected, this));  	} +    mButtonsContainer = getChild<LLPanel>("button_layout_panel"); +    mButtonsContainer->setVisible(FALSE); +    mFilterContainer = getChild<LLLayoutStack>("top_menu_panel"); +  	mFilterEditor = getChild<LLFilterEditor>("Filter");  	if (mFilterEditor)  	{ @@ -388,7 +411,22 @@ void LLPanelPlaces::onOpen(const LLSD& key)  			// Update the buttons at the bottom of the panel  			updateVerbs();  		} -		else +        else if (key_type == CREATE_PICK_TYPE) +        { +            LLUUID item_id = key["item_id"]; + +            LLLandmarksPanel* landmarks_panel = +                dynamic_cast<LLLandmarksPanel*>(mTabContainer->getPanelByName("Landmarks")); +            if (landmarks_panel && item_id.notNull()) +            { +                LLLandmark* landmark = LLLandmarkActions::getLandmark(item_id, boost::bind(&LLLandmarksPanel::doCreatePick, landmarks_panel, _1, item_id)); +                if (landmark) +                { +                    landmarks_panel->doCreatePick(landmark, item_id); +                } +            } +        } +		else // "create_landmark"  		{  			mFilterEditor->clear();  			onFilterEdit("", false); @@ -409,7 +447,8 @@ void LLPanelPlaces::onOpen(const LLSD& key)  			}  			else if (mPlaceInfoType == CREATE_LANDMARK_INFO_TYPE)  			{ -				mLandmarkInfo->setInfoType(LLPanelPlaceInfo::CREATE_LANDMARK); +				LLUUID dest_folder = key["dest_folder"]; +				mLandmarkInfo->setInfoAndCreateLandmark(dest_folder);  				if (key.has("x") && key.has("y") && key.has("z"))  				{ @@ -612,6 +651,23 @@ void LLPanelPlaces::onTabSelected()  	onFilterEdit(mActivePanel->getFilterSubString(), true);  	mActivePanel->updateVerbs(); + +    // History panel does not support deletion nor creation +    // Hide menus +    bool supports_create = mActivePanel->getCreateMenu() != NULL; +    childSetVisible("add_btn_panel", supports_create); + +    // favorites and inventory can remove items, history can clear history +    childSetVisible("trash_btn_panel", TRUE); + +    if (supports_create) +    { +        mRemoveSelectedBtn->setToolTip(getString("tooltip_trash_items")); +    } +    else +    { +        mRemoveSelectedBtn->setToolTip(getString("tooltip_trash_history")); +    }  }  void LLPanelPlaces::onTeleportButtonClicked() @@ -728,34 +784,6 @@ void LLPanelPlaces::onEditButtonClicked()  	updateVerbs();  } -class LLUpdateLandmarkParent : public LLInventoryCallback -{ -public: -    LLUpdateLandmarkParent(LLPointer<LLViewerInventoryItem> item, LLUUID new_parent) : -        mItem(item), -        mNewParentId(new_parent) -    {}; -    /* virtual */ void fire(const LLUUID& inv_item_id) -    { -        LLInventoryModel::update_list_t update; -        LLInventoryModel::LLCategoryUpdate old_folder(mItem->getParentUUID(), -1); -        update.push_back(old_folder); -        LLInventoryModel::LLCategoryUpdate new_folder(mNewParentId, 1); -        update.push_back(new_folder); -        gInventory.accountForUpdate(update); - -        mItem->setParent(mNewParentId); -        mItem->updateParentOnServer(FALSE); - -        gInventory.updateItem(mItem); -        gInventory.notifyObservers(); -    } - -private: -    LLPointer<LLViewerInventoryItem> mItem; -    LLUUID mNewParentId; -}; -  void LLPanelPlaces::onSaveButtonClicked()  {  	if (!mLandmarkInfo || mItem.isNull()) @@ -885,14 +913,6 @@ void LLPanelPlaces::onOverflowButtonClicked()  	mOverflowBtn->setMenu(menu, LLMenuButton::MP_TOP_RIGHT);  } -void LLPanelPlaces::onProfileButtonClicked() -{ -	if (!mActivePanel) -		return; - -	mActivePanel->onShowProfile(); -} -  bool LLPanelPlaces::onOverflowMenuItemEnable(const LLSD& param)  {  	std::string value = param.asString(); @@ -981,6 +1001,50 @@ void LLPanelPlaces::onBackButtonClicked()  	updateVerbs();  } +void LLPanelPlaces::onGearMenuClick() +{ +    if (mActivePanel) +    { +        LLToggleableMenu* menu = mActivePanel->getSelectionMenu(); +        mGearMenuButton->setMenu(menu, LLMenuButton::MP_BOTTOM_LEFT); +    } +} + +void LLPanelPlaces::onSortingMenuClick() +{ +    if (mActivePanel) +    { +        LLToggleableMenu* menu = mActivePanel->getSortingMenu(); +        mSortingMenuButton->setMenu(menu, LLMenuButton::MP_BOTTOM_LEFT); +    } +} + +void LLPanelPlaces::onAddMenuClick() +{ +    if (mActivePanel) +    { +        LLToggleableMenu* menu = mActivePanel->getCreateMenu(); +        mAddMenuButton->setMenu(menu, LLMenuButton::MP_BOTTOM_LEFT); +    } +} + +void LLPanelPlaces::onRemoveButtonClicked() +{ +    if (mActivePanel) +    { +        mActivePanel->onRemoveSelected(); +    } +} + +bool LLPanelPlaces::handleDragAndDropToTrash(BOOL drop, EDragAndDropType cargo_type, void* cargo_data, EAcceptance* accept) +{ +    if (mActivePanel) +    { +        return mActivePanel->handleDragAndDropToTrash(drop, cargo_type, cargo_data, accept); +    } +    return false; +} +  void LLPanelPlaces::togglePickPanel(BOOL visible)  {  	if (mPickPanel) @@ -997,8 +1061,9 @@ void LLPanelPlaces::togglePlaceInfoPanel(BOOL visible)  	if (!mPlaceProfile || !mLandmarkInfo)  		return; -	mFilterEditor->setVisible(!visible);  	mTabContainer->setVisible(!visible); +	mButtonsContainer->setVisible(visible); +	mFilterContainer->setVisible(!visible);  	if (mPlaceInfoType == AGENT_INFO_TYPE ||  		mPlaceInfoType == REMOTE_PLACE_INFO_TYPE || @@ -1014,10 +1079,6 @@ void LLPanelPlaces::togglePlaceInfoPanel(BOOL visible)  			// to avoid text blinking.  			mResetInfoTimer.setTimerExpirySec(PLACE_INFO_UPDATE_INTERVAL); -			LLRect rect = getRect(); -			LLRect new_rect = LLRect(rect.mLeft, rect.mTop, rect.mRight, mTabContainer->getRect().mBottom); -			mPlaceProfile->reshape(new_rect.getWidth(), new_rect.getHeight()); -  			mLandmarkInfo->setVisible(FALSE);  		}  		else if (mPlaceInfoType == AGENT_INFO_TYPE) @@ -1038,15 +1099,19 @@ void LLPanelPlaces::togglePlaceInfoPanel(BOOL visible)  		if (visible)  		{  			mLandmarkInfo->resetLocation(); - -			LLRect rect = getRect(); -			LLRect new_rect = LLRect(rect.mLeft, rect.mTop, rect.mRight, mTabContainer->getRect().mBottom); -			mLandmarkInfo->reshape(new_rect.getWidth(), new_rect.getHeight());  		}  		else  		{ -			LLLandmarksPanel* landmarks_panel = -					dynamic_cast<LLLandmarksPanel*>(mTabContainer->getPanelByName("Landmarks")); +			std::string tab_panel_name("Landmarks"); +			if (mItem.notNull()) +			{ +				if (gInventory.isObjectDescendentOf(mItem->getUUID(), gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE))) +				{ +					tab_panel_name = "Favorites"; +				} +			} +			 +			LLLandmarksPanel* landmarks_panel = dynamic_cast<LLLandmarksPanel*>(mTabContainer->getPanelByName(tab_panel_name));  			if (landmarks_panel)  			{  				// If a landmark info is being closed we open the landmarks tab @@ -1056,6 +1121,10 @@ void LLPanelPlaces::togglePlaceInfoPanel(BOOL visible)  				{  					landmarks_panel->setItemSelected(mItem->getUUID(), TRUE);  				} +				else +				{ +					landmarks_panel->resetSelection(); +				}  			}  		}  	} @@ -1123,11 +1192,19 @@ void LLPanelPlaces::createTabs()  	if (!(gInventory.isInventoryUsable() && LLTeleportHistory::getInstance() && !mTabsCreated))  		return; +	LLFavoritesPanel* favorites_panel = new LLFavoritesPanel(); +	if (favorites_panel) +	{ +		mTabContainer->addTabPanel( +			LLTabContainer::TabPanelParams(). +			panel(favorites_panel). +			label(getString("favorites_tab_title")). +			insert_at(LLTabContainer::END)); +	} +  	LLLandmarksPanel* landmarks_panel = new LLLandmarksPanel();  	if (landmarks_panel)  	{ -		landmarks_panel->setPanelPlacesButtons(this); -  		mTabContainer->addTabPanel(  			LLTabContainer::TabPanelParams().  			panel(landmarks_panel). @@ -1138,8 +1215,6 @@ void LLPanelPlaces::createTabs()  	LLTeleportHistoryPanel* teleport_history_panel = new LLTeleportHistoryPanel();  	if (teleport_history_panel)  	{ -		teleport_history_panel->setPanelPlacesButtons(this); -  		mTabContainer->addTabPanel(  			LLTabContainer::TabPanelParams().  			panel(teleport_history_panel). @@ -1151,9 +1226,31 @@ void LLPanelPlaces::createTabs()  	mActivePanel = dynamic_cast<LLPanelPlacesTab*>(mTabContainer->getCurrentPanel()); -	// Filter applied to show all items. -	if (mActivePanel) -		mActivePanel->onSearchEdit(mActivePanel->getFilterSubString()); +    if (mActivePanel) +    { +        // Filter applied to show all items. +        mActivePanel->onSearchEdit(mActivePanel->getFilterSubString()); + +        // History panel does not support deletion nor creation +        // Hide menus +        bool supports_create = mActivePanel->getCreateMenu() != NULL; +        childSetVisible("add_btn_panel", supports_create); + +        // favorites and inventory can remove items, history can clear history +        childSetVisible("trash_btn_panel", TRUE); + +        if (supports_create) +        { +            mRemoveSelectedBtn->setToolTip(getString("tooltip_trash_items")); +        } +        else +        { +            mRemoveSelectedBtn->setToolTip(getString("tooltip_trash_history")); +        } + +        mActivePanel->setRemoveBtn(mRemoveSelectedBtn); +		mActivePanel->updateVerbs(); +    }  	mTabsCreated = true;  } @@ -1219,15 +1316,12 @@ void LLPanelPlaces::updateVerbs()  	mSaveBtn->setVisible(isLandmarkEditModeOn);  	mCancelBtn->setVisible(isLandmarkEditModeOn);  	mCloseBtn->setVisible(is_create_landmark_visible && !isLandmarkEditModeOn); -	mPlaceInfoBtn->setVisible(!is_place_info_visible && !is_create_landmark_visible && !isLandmarkEditModeOn && !is_pick_panel_visible);  	bool show_options_btn = is_place_info_visible && !is_create_landmark_visible && !isLandmarkEditModeOn;  	mOverflowBtn->setVisible(show_options_btn);  	getChild<LLLayoutPanel>("lp_options")->setVisible(show_options_btn);  	getChild<LLLayoutPanel>("lp2")->setVisible(!show_options_btn); -	mPlaceInfoBtn->setEnabled(!is_create_landmark_visible && !isLandmarkEditModeOn && have_3d_pos); -  	if (is_place_info_visible)  	{  		mShowOnMapBtn->setEnabled(have_3d_pos); diff --git a/indra/newview/llpanelplaces.h b/indra/newview/llpanelplaces.h index 978b030b2e..3b87eb6cb9 100644 --- a/indra/newview/llpanelplaces.h +++ b/indra/newview/llpanelplaces.h @@ -48,6 +48,7 @@ class LLRemoteParcelInfoObserver;  class LLTabContainer;  class LLToggleableMenu;  class LLMenuButton; +class LLLayoutStack;  typedef std::pair<LLUUID, std::string>	folder_pair_t; @@ -96,7 +97,12 @@ private:  	bool onOverflowMenuItemEnable(const LLSD& param);  	void onCreateLandmarkButtonClicked(const LLUUID& folder_id);  	void onBackButtonClicked(); -	void onProfileButtonClicked(); +    void onGearMenuClick(); +    void onSortingMenuClick(); +    void onAddMenuClick(); +    void onRemoveButtonClicked(); +    bool handleDragAndDropToTrash(BOOL drop, EDragAndDropType cargo_type, void* cargo_data, EAcceptance* accept); +  	void toggleMediaPanel();  	void togglePickPanel(BOOL visible); @@ -111,6 +117,8 @@ private:  	LLFilterEditor*				mFilterEditor;  	LLPanelPlacesTab*			mActivePanel;  	LLTabContainer*				mTabContainer; +	LLPanel*					mButtonsContainer; +	LLLayoutStack*				mFilterContainer;  	LLPanelPlaceProfile*		mPlaceProfile;  	LLPanelLandmarkInfo*		mLandmarkInfo; @@ -125,7 +133,12 @@ private:  	LLButton*					mCancelBtn;  	LLButton*					mCloseBtn;  	LLMenuButton*				mOverflowBtn; -	LLButton*					mPlaceInfoBtn; + +    // Top menu +    LLMenuButton*				mGearMenuButton; +    LLMenuButton*				mSortingMenuButton; +    LLMenuButton*				mAddMenuButton; +    LLButton*					mRemoveSelectedBtn;  	LLPlacesInventoryObserver*	mInventoryObserver;  	LLPlacesParcelObserver*		mParcelObserver; diff --git a/indra/newview/llpanelplacestab.cpp b/indra/newview/llpanelplacestab.cpp index 9644b7518e..748a917147 100644 --- a/indra/newview/llpanelplacestab.cpp +++ b/indra/newview/llpanelplacestab.cpp @@ -38,6 +38,7 @@  #include "llworldmap.h"  std::string LLPanelPlacesTab::sFilterSubString = LLStringUtil::null; +LLButton* LLPanelPlacesTab::sRemoveBtn = NULL;  bool LLPanelPlacesTab::isTabVisible()  { @@ -47,13 +48,6 @@ bool LLPanelPlacesTab::isTabVisible()  	return true;  } -void LLPanelPlacesTab::setPanelPlacesButtons(LLPanelPlaces* panel) -{ -	mTeleportBtn = panel->getChild<LLButton>("teleport_btn"); -	mShowOnMapBtn = panel->getChild<LLButton>("map_btn"); -	mShowProfile = panel->getChild<LLButton>("profile_btn"); -} -  void LLPanelPlacesTab::onRegionResponse(const LLVector3d& landmark_global_pos,  										U64 region_handle,  										const std::string& url, diff --git a/indra/newview/llpanelplacestab.h b/indra/newview/llpanelplacestab.h index 367ce46e2e..aab1c130c1 100644 --- a/indra/newview/llpanelplacestab.h +++ b/indra/newview/llpanelplacestab.h @@ -30,6 +30,7 @@  #include "llpanel.h"  class LLPanelPlaces; +class LLToggleableMenu;  class LLPanelPlacesTab : public LLPanel  { @@ -42,11 +43,21 @@ public:  	virtual void onShowOnMap() = 0;  	virtual void onShowProfile() = 0;  	virtual void onTeleport() = 0; +	virtual void onRemoveSelected() = 0;  	virtual bool isSingleItemSelected() = 0; +    // returns menu for current selection +    virtual LLToggleableMenu* getSelectionMenu() = 0; +    virtual LLToggleableMenu* getSortingMenu() = 0; +    virtual LLToggleableMenu* getCreateMenu() = 0; + +    /** +    * Processes drag-n-drop of the Landmarks and folders into trash button. +    */ +    virtual bool handleDragAndDropToTrash(BOOL drop, EDragAndDropType cargo_type, void* cargo_data, EAcceptance* accept) = 0; +  	bool isTabVisible(); // Check if parent TabContainer is visible. -	void setPanelPlacesButtons(LLPanelPlaces* panel);  	void onRegionResponse(const LLVector3d& landmark_global_pos,  										U64 region_handle,  										const std::string& url, @@ -56,13 +67,12 @@ public:  	const std::string& getFilterSubString() { return sFilterSubString; }  	void setFilterSubString(const std::string& string) { sFilterSubString = string; } -protected: -	LLButton*				mTeleportBtn; -	LLButton*				mShowOnMapBtn; -	LLButton*				mShowProfile; +	void setRemoveBtn(LLButton* trash_btn) { sRemoveBtn = trash_btn; } +protected:  	// Search string for filtering landmarks and teleport history locations  	static std::string		sFilterSubString; +	static LLButton*		sRemoveBtn;  };  #endif //LL_LLPANELPLACESTAB_H diff --git a/indra/newview/llpanelteleporthistory.cpp b/indra/newview/llpanelteleporthistory.cpp index fe0608d544..b938b30479 100644 --- a/indra/newview/llpanelteleporthistory.cpp +++ b/indra/newview/llpanelteleporthistory.cpp @@ -56,7 +56,7 @@ static const std::string COLLAPSED_BY_USER = "collapsed_by_user";  class LLTeleportHistoryFlatItem : public LLPanel  {  public: -	LLTeleportHistoryFlatItem(S32 index, LLTeleportHistoryPanel::ContextMenu *context_menu, const std::string ®ion_name, +	LLTeleportHistoryFlatItem(S32 index, LLToggleableMenu *menu, const std::string ®ion_name,  										 	 LLDate date, const std::string &hl);  	virtual ~LLTeleportHistoryFlatItem(); @@ -86,12 +86,13 @@ public:  private:  	void onProfileBtnClick(); +    void showMenu(S32 x, S32 y);  	LLButton* mProfileBtn;  	LLTextBox* mTitle;  	LLTextBox* mTimeTextBox; -	LLTeleportHistoryPanel::ContextMenu *mContextMenu; +	LLToggleableMenu *mMenu;  	S32 mIndex;  	std::string mRegionName; @@ -112,7 +113,7 @@ protected:  public:  	LLTeleportHistoryFlatItem* getFlatItemForPersistentItem ( -		LLTeleportHistoryPanel::ContextMenu *context_menu, +		LLToggleableMenu *menu,  		const LLTeleportHistoryPersistentItem& persistent_item,  		const S32 cur_item_index,  		const std::string &hl); @@ -130,16 +131,16 @@ private:  ////////////////////////////////////////////////////////////////////////////////  //////////////////////////////////////////////////////////////////////////////// -LLTeleportHistoryFlatItem::LLTeleportHistoryFlatItem(S32 index, LLTeleportHistoryPanel::ContextMenu *context_menu, const std::string ®ion_name, +LLTeleportHistoryFlatItem::LLTeleportHistoryFlatItem(S32 index, LLToggleableMenu *menu, const std::string ®ion_name,  																LLDate date, const std::string &hl)  :	LLPanel(),  	mIndex(index), -	mContextMenu(context_menu), +	mMenu(menu),  	mRegionName(region_name),  	mDate(date),  	mHighlight(hl)  { -	buildFromFile( "panel_teleport_history_item.xml"); +	buildFromFile("panel_teleport_history_item.xml");  }  LLTeleportHistoryFlatItem::~LLTeleportHistoryFlatItem() @@ -266,10 +267,9 @@ void LLTeleportHistoryFlatItem::onMouseLeave(S32 x, S32 y, MASK mask)  // virtual  BOOL LLTeleportHistoryFlatItem::handleRightMouseDown(S32 x, S32 y, MASK mask)  { -	if (mContextMenu) -		mContextMenu->show(this, mIndex, x, y); - -	return LLPanel::handleRightMouseDown(x, y, mask); +    LLPanel::handleRightMouseDown(x, y, mask); +	showMenu(x, y); +    return TRUE;  }  void LLTeleportHistoryFlatItem::showPlaceInfoPanel(S32 index) @@ -286,13 +286,23 @@ void LLTeleportHistoryFlatItem::onProfileBtnClick()  	LLTeleportHistoryFlatItem::showPlaceInfoPanel(mIndex);  } +void LLTeleportHistoryFlatItem::showMenu(S32 x, S32 y) +{ +    mMenu->setButtonRect(this); +    mMenu->buildDrawLabels(); +    mMenu->arrangeAndClear(); +    mMenu->updateParent(LLMenuGL::sMenuContainer); + +    LLMenuGL::showPopup(this, mMenu, x, y); +} +  ////////////////////////////////////////////////////////////////////////////////  ////////////////////////////////////////////////////////////////////////////////  ////////////////////////////////////////////////////////////////////////////////  LLTeleportHistoryFlatItem*  LLTeleportHistoryFlatItemStorage::getFlatItemForPersistentItem ( -	LLTeleportHistoryPanel::ContextMenu *context_menu, +	LLToggleableMenu *menu,  	const LLTeleportHistoryPersistentItem& persistent_item,  	const S32 cur_item_index,  	const std::string &hl) @@ -321,7 +331,7 @@ LLTeleportHistoryFlatItemStorage::getFlatItemForPersistentItem (  	if ( !item )  	{  		item = new LLTeleportHistoryFlatItem(cur_item_index, -											 context_menu, +											 menu,  											 persistent_item.mTitle,  											 persistent_item.mDate,  											 hl); @@ -365,74 +375,6 @@ void LLTeleportHistoryFlatItemStorage::purge()  ////////////////////////////////////////////////////////////////////////////////  //////////////////////////////////////////////////////////////////////////////// -LLTeleportHistoryPanel::ContextMenu::ContextMenu() : -	mMenu(NULL), mIndex(0) -{ -} - -void LLTeleportHistoryPanel::ContextMenu::show(LLView* spawning_view, S32 index, S32 x, S32 y) -{ -	if (mMenu) -	{ -		//preventing parent (menu holder) from deleting already "dead" context menus on exit -		LLView* parent = mMenu->getParent(); -		if (parent) -		{ -			parent->removeChild(mMenu); -		} -		delete mMenu; -	} - -	mIndex = index; -	mMenu = createMenu(); - -	mMenu->show(x, y); -	LLMenuGL::showPopup(spawning_view, mMenu, x, y); -} - -LLContextMenu* LLTeleportHistoryPanel::ContextMenu::createMenu() -{ -	// set up the callbacks for all of the avatar menu items -	// (N.B. callbacks don't take const refs as mID is local scope) -	LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; - -	registrar.add("TeleportHistory.Teleport",	boost::bind(&LLTeleportHistoryPanel::ContextMenu::onTeleport, this)); -	registrar.add("TeleportHistory.MoreInformation",boost::bind(&LLTeleportHistoryPanel::ContextMenu::onInfo, this)); -	registrar.add("TeleportHistory.CopyToClipboard",boost::bind(&LLTeleportHistoryPanel::ContextMenu::onCopyToClipboard, this)); - -	// create the context menu from the XUI -	llassert(LLMenuGL::sMenuContainer != NULL); -	return LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>( -		"menu_teleport_history_item.xml", LLMenuGL::sMenuContainer, LLViewerMenuHolderGL::child_registry_t::instance()); -} - -void LLTeleportHistoryPanel::ContextMenu::onTeleport() -{ -	confirmTeleport(mIndex); -} - -void LLTeleportHistoryPanel::ContextMenu::onInfo() -{ -	LLTeleportHistoryFlatItem::showPlaceInfoPanel(mIndex); -} - -//static -void LLTeleportHistoryPanel::ContextMenu::gotSLURLCallback(const std::string& slurl) -{ -	LLClipboard::instance().copyToClipboard(utf8str_to_wstring(slurl),0,slurl.size()); - -	LLSD args; -	args["SLURL"] = slurl; - -	LLNotificationsUtil::add("CopySLURL", args); -} - -void LLTeleportHistoryPanel::ContextMenu::onCopyToClipboard() -{ -	LLVector3d globalPos = LLTeleportHistoryStorage::getInstance()->getItems()[mIndex].mGlobalPos; -	LLLandmarkActions::getSLURLfromPosGlobal(globalPos, -		boost::bind(&LLTeleportHistoryPanel::ContextMenu::gotSLURLCallback, _1)); -}  // Not yet implemented; need to remove buildPanel() from constructor when we switch  //static LLRegisterPanelClassWrapper<LLTeleportHistoryPanel> t_teleport_history("panel_teleport_history"); @@ -446,7 +388,8 @@ LLTeleportHistoryPanel::LLTeleportHistoryPanel()  		mAccordionTabMenu(NULL),  		mLastSelectedFlatlList(NULL),  		mLastSelectedItemIndex(-1), -		mMenuGearButton(NULL) +		mGearItemMenu(NULL), +		mSortingMenu(NULL)  {  	buildFromFile( "panel_teleport_history.xml");  } @@ -454,12 +397,19 @@ LLTeleportHistoryPanel::LLTeleportHistoryPanel()  LLTeleportHistoryPanel::~LLTeleportHistoryPanel()  {  	LLTeleportHistoryFlatItemStorage::instance().purge(); -	if (mGearMenuHandle.get()) mGearMenuHandle.get()->die();  	mTeleportHistoryChangedConnection.disconnect();  }  BOOL LLTeleportHistoryPanel::postBuild()  { +    mCommitCallbackRegistrar.add("TeleportHistory.GearMenu.Action", boost::bind(&LLTeleportHistoryPanel::onGearMenuAction, this, _2)); +    mEnableCallbackRegistrar.add("TeleportHistory.GearMenu.Enable", boost::bind(&LLTeleportHistoryPanel::isActionEnabled, this, _2)); + +    // init menus before list, since menus are passed to list +    mGearItemMenu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_teleport_history_item.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); +    mGearItemMenu->setAlwaysShowMenu(TRUE); // all items can be disabled if nothing is selected, show anyway +    mSortingMenu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_teleport_history_gear.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); +  	mTeleportHistory = LLTeleportHistoryStorage::getInstance();  	if (mTeleportHistory)  	{ @@ -511,22 +461,6 @@ BOOL LLTeleportHistoryPanel::postBuild()  		}  	} -	LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; - -	registrar.add("TeleportHistory.ExpandAllFolders",  boost::bind(&LLTeleportHistoryPanel::onExpandAllFolders,  this)); -	registrar.add("TeleportHistory.CollapseAllFolders",  boost::bind(&LLTeleportHistoryPanel::onCollapseAllFolders,  this)); -	registrar.add("TeleportHistory.ClearTeleportHistory",  boost::bind(&LLTeleportHistoryPanel::onClearTeleportHistory,  this)); -	mEnableCallbackRegistrar.add("TeleportHistory.GearMenu.Enable", boost::bind(&LLTeleportHistoryPanel::isActionEnabled, this, _2)); - -	mMenuGearButton = getChild<LLMenuButton>("gear_btn"); - -	LLToggleableMenu* gear_menu  = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_teleport_history_gear.xml",  gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());; -	if(gear_menu) -	{ -		mGearMenuHandle  = gear_menu->getHandle(); -		mMenuGearButton->setMenu(gear_menu); -	} -  	return TRUE;  } @@ -600,6 +534,12 @@ void LLTeleportHistoryPanel::onTeleport()  	confirmTeleport(itemp->getIndex());  } +// virtual +void LLTeleportHistoryPanel::onRemoveSelected() +{ +    LLNotificationsUtil::add("ConfirmClearTeleportHistory", LLSD(), LLSD(), boost::bind(&LLTeleportHistoryPanel::onClearTeleportHistoryDialog, this, _1, _2)); +} +  /*  // virtual  void LLTeleportHistoryPanel::onCopySLURL() @@ -630,19 +570,28 @@ void LLTeleportHistoryPanel::updateVerbs()  	if (!isTabVisible())  		return; -	if (!mLastSelectedFlatlList) +	if (sRemoveBtn)  	{ -		mTeleportBtn->setEnabled(false); -		mShowProfile->setEnabled(false); -		mShowOnMapBtn->setEnabled(false); -		return; +		sRemoveBtn->setEnabled(true);  	} +} -	LLTeleportHistoryFlatItem* itemp = dynamic_cast<LLTeleportHistoryFlatItem *> (mLastSelectedFlatlList->getSelectedItem()); +// virtual +LLToggleableMenu* LLTeleportHistoryPanel::getSelectionMenu() +{ +    return mGearItemMenu; +} + +// virtual +LLToggleableMenu* LLTeleportHistoryPanel::getSortingMenu() +{ +    return mSortingMenu; +} -	mTeleportBtn->setEnabled(NULL != itemp); -	mShowProfile->setEnabled(NULL != itemp); -	mShowOnMapBtn->setEnabled(NULL != itemp); +// virtual +LLToggleableMenu* LLTeleportHistoryPanel::getCreateMenu() +{ +    return NULL;  }  void LLTeleportHistoryPanel::getNextTab(const LLDate& item_date, S32& tab_idx, LLDate& tab_date) @@ -778,7 +727,7 @@ void LLTeleportHistoryPanel::refresh()  		{  			LLTeleportHistoryFlatItem* item =  				LLTeleportHistoryFlatItemStorage::instance() -				.getFlatItemForPersistentItem(&mContextMenu, +				.getFlatItemForPersistentItem(mGearItemMenu,  											  items[mCurrentItem],  											  mCurrentItem,  											  filter_string); @@ -847,7 +796,7 @@ void LLTeleportHistoryPanel::replaceItem(S32 removed_index)  	const LLTeleportHistoryStorage::slurl_list_t& history_items = mTeleportHistory->getItems();  	LLTeleportHistoryFlatItem* item = LLTeleportHistoryFlatItemStorage::instance() -		.getFlatItemForPersistentItem(&mContextMenu, +		.getFlatItemForPersistentItem(mGearItemMenu,  									  history_items[history_items.size() - 1], // Most recent item, it was added instead of removed  									  history_items.size(), // index will be decremented inside loop below  									  sFilterSubString); @@ -1019,38 +968,6 @@ void LLTeleportHistoryPanel::onAccordionTabClose(LLAccordionCtrlTab *tab)  	mHistoryAccordion->arrange();  } -void LLTeleportHistoryPanel::onExpandAllFolders() -{ -	S32 tabs_cnt = mItemContainers.size(); - -	for (S32 n = 0; n < tabs_cnt; n++) -	{ -		mItemContainers.at(n)->setDisplayChildren(true); -	} -	mHistoryAccordion->arrange(); -} - -void LLTeleportHistoryPanel::onCollapseAllFolders() -{ -	S32 tabs_cnt = mItemContainers.size(); - -	for (S32 n = 0; n < tabs_cnt; n++) -	{ -		mItemContainers.at(n)->setDisplayChildren(false); -	} -	mHistoryAccordion->arrange(); - -	if (mLastSelectedFlatlList) -	{ -		mLastSelectedFlatlList->resetSelection(); -	} -} - -void LLTeleportHistoryPanel::onClearTeleportHistory() -{ -	LLNotificationsUtil::add("ConfirmClearTeleportHistory", LLSD(), LLSD(), boost::bind(&LLTeleportHistoryPanel::onClearTeleportHistoryDialog, this, _1, _2)); -} -  bool LLTeleportHistoryPanel::onClearTeleportHistoryDialog(const LLSD& notification, const LLSD& response)  { @@ -1082,45 +999,137 @@ LLFlatListView* LLTeleportHistoryPanel::getFlatListViewFromTab(LLAccordionCtrlTa  	return NULL;  } -bool LLTeleportHistoryPanel::isActionEnabled(const LLSD& userdata) const +void LLTeleportHistoryPanel::gotSLURLCallback(const std::string& slurl)  { -	S32 tabs_cnt = mItemContainers.size(); - -	bool has_expanded_tabs = false; -	bool has_collapsed_tabs = false; - -	for (S32 n = 0; n < tabs_cnt; n++) -	{ -		LLAccordionCtrlTab* tab = mItemContainers.at(n); -		if (!tab->getVisible()) -			continue; - -		if (tab->getDisplayChildren()) -		{ -			has_expanded_tabs = true; -		} -		else -		{ -			has_collapsed_tabs = true; -		} +    LLClipboard::instance().copyToClipboard(utf8str_to_wstring(slurl), 0, slurl.size()); -		if (has_expanded_tabs && has_collapsed_tabs) -		{ -			break; -		} -	} +    LLSD args; +    args["SLURL"] = slurl; -	std::string command_name = userdata.asString(); +    LLNotificationsUtil::add("CopySLURL", args); +} -	if (has_expanded_tabs && command_name == "collapse_all") -	{ -		return true; -	} +void LLTeleportHistoryPanel::onGearMenuAction(const LLSD& userdata) +{ +    std::string command_name = userdata.asString(); + +    if ("expand_all" == command_name) +    { +        S32 tabs_cnt = mItemContainers.size(); + +        for (S32 n = 0; n < tabs_cnt; n++) +        { +            mItemContainers.at(n)->setDisplayChildren(true); +        } +        mHistoryAccordion->arrange(); +    } +    else if ("collapse_all" == command_name) +    { +        S32 tabs_cnt = mItemContainers.size(); + +        for (S32 n = 0; n < tabs_cnt; n++) +        { +            mItemContainers.at(n)->setDisplayChildren(false); +        } +        mHistoryAccordion->arrange(); + +        if (mLastSelectedFlatlList) +        { +            mLastSelectedFlatlList->resetSelection(); +        } +    } + +    S32 index = -1; +    if (mLastSelectedFlatlList) +    { +        LLTeleportHistoryFlatItem* itemp = dynamic_cast<LLTeleportHistoryFlatItem *> (mLastSelectedFlatlList->getSelectedItem()); +        if (itemp) +        { +            index = itemp->getIndex(); +        } +    } + +    if ("teleport" == command_name) +    { +        confirmTeleport(index); +    } +    else if ("view" == command_name) +    { +        LLTeleportHistoryFlatItem::showPlaceInfoPanel(index); +    } +    else if ("show_on_map" == command_name) +    { +        LLTeleportHistoryStorage::getInstance()->showItemOnMap(index); +    } +    else if ("copy_slurl" == command_name) +    { +        LLVector3d globalPos = LLTeleportHistoryStorage::getInstance()->getItems()[index].mGlobalPos; +        LLLandmarkActions::getSLURLfromPosGlobal(globalPos, +            boost::bind(&LLTeleportHistoryPanel::gotSLURLCallback, _1)); +    } +} -	if (has_collapsed_tabs && command_name ==  "expand_all") -	{ -		return true; -	} +bool LLTeleportHistoryPanel::isActionEnabled(const LLSD& userdata) const +{ +    std::string command_name = userdata.asString(); + +    if (command_name == "collapse_all" +        || command_name == "expand_all") +    { +        S32 tabs_cnt = mItemContainers.size(); + +        bool has_expanded_tabs = false; +        bool has_collapsed_tabs = false; + +        for (S32 n = 0; n < tabs_cnt; n++) +        { +            LLAccordionCtrlTab* tab = mItemContainers.at(n); +            if (!tab->getVisible()) +                continue; + +            if (tab->getDisplayChildren()) +            { +                has_expanded_tabs = true; +            } +            else +            { +                has_collapsed_tabs = true; +            } + +            if (has_expanded_tabs && has_collapsed_tabs) +            { +                break; +            } +        } + +        if (command_name == "collapse_all") +        { +            return has_expanded_tabs; +        } + +        if (command_name == "expand_all") +        { +            return has_collapsed_tabs; +        } +    } + +    if (command_name == "clear_history") +    { +        return mTeleportHistory->getItems().size() > 0; +    } +     +    if ("teleport" == command_name +        || "view" == command_name +        || "show_on_map" == command_name +        || "copy_slurl" == command_name) +    { +        if (!mLastSelectedFlatlList) +        { +            return false; +        } +        LLTeleportHistoryFlatItem* itemp = dynamic_cast<LLTeleportHistoryFlatItem *> (mLastSelectedFlatlList->getSelectedItem()); +        return itemp != NULL; +    }  	return false;  } diff --git a/indra/newview/llpanelteleporthistory.h b/indra/newview/llpanelteleporthistory.h index b88861c5c6..058fee0170 100644 --- a/indra/newview/llpanelteleporthistory.h +++ b/indra/newview/llpanelteleporthistory.h @@ -43,38 +43,26 @@ class LLMenuButton;  class LLTeleportHistoryPanel : public LLPanelPlacesTab  {  public: -	// *TODO: derive from LLListContextMenu? -	class ContextMenu -	{ -	public: -		ContextMenu(); -		void show(LLView* spawning_view, S32 index, S32 x, S32 y); - -	private: -		LLContextMenu* createMenu(); -		void onTeleport(); -		void onInfo(); -		void onCopyToClipboard(); - -		static void gotSLURLCallback(const std::string& slurl); - -		LLContextMenu* mMenu; -		S32 mIndex; -	}; -  	LLTeleportHistoryPanel();  	virtual ~LLTeleportHistoryPanel(); -	/*virtual*/ BOOL postBuild(); -	/*virtual*/ void draw(); +    BOOL postBuild() override; +    void draw() override; -	/*virtual*/ void onSearchEdit(const std::string& string); -	/*virtual*/ void onShowOnMap(); -	/*virtual*/ void onShowProfile(); -	/*virtual*/ void onTeleport(); -	///*virtual*/ void onCopySLURL(); -	/*virtual*/ void updateVerbs(); -	/*virtual*/ bool isSingleItemSelected(); +    void onSearchEdit(const std::string& string) override; +    void onShowOnMap() override; +    void onShowProfile() override; +    void onTeleport() override; +    ///*virtual*/ void onCopySLURL(); +    void onRemoveSelected() override; +    void updateVerbs() override; +    bool isSingleItemSelected() override; + +    LLToggleableMenu* getSelectionMenu() override; +    LLToggleableMenu* getSortingMenu() override; +    LLToggleableMenu* getCreateMenu() override; + +    bool handleDragAndDropToTrash(BOOL drop, EDragAndDropType cargo_type, void* cargo_data, EAcceptance* accept) override { return false; }  private: @@ -88,13 +76,15 @@ private:  	void onClearTeleportHistory();  	bool onClearTeleportHistoryDialog(const LLSD& notification, const LLSD& response); -	void refresh(); +	void refresh() override;  	void getNextTab(const LLDate& item_date, S32& curr_tab, LLDate& tab_date);  	void onTeleportHistoryChange(S32 removed_index);  	void replaceItem(S32 removed_index);  	void showTeleportHistory();  	void handleItemSelect(LLFlatListView* );  	LLFlatListView* getFlatListViewFromTab(LLAccordionCtrlTab *); +	static void gotSLURLCallback(const std::string& slurl); +	void onGearMenuAction(const LLSD& userdata);  	bool isActionEnabled(const LLSD& userdata) const;  	void setAccordionCollapsedByUser(LLUICtrl* acc_tab, bool collapsed); @@ -115,10 +105,10 @@ private:  	typedef std::vector<LLAccordionCtrlTab*> item_containers_t;  	item_containers_t mItemContainers; -	ContextMenu mContextMenu;  	LLContextMenu*			mAccordionTabMenu; -	LLHandle<LLView>		mGearMenuHandle; -	LLMenuButton*			mMenuGearButton; + +    LLToggleableMenu*			mGearItemMenu; +    LLToggleableMenu*			mSortingMenu;  	boost::signals2::connection mTeleportHistoryChangedConnection;  }; diff --git a/indra/newview/llpaneltopinfobar.cpp b/indra/newview/llpaneltopinfobar.cpp index 109013498e..0723a78704 100644 --- a/indra/newview/llpaneltopinfobar.cpp +++ b/indra/newview/llpaneltopinfobar.cpp @@ -31,6 +31,7 @@  #include "llagent.h"  #include "llagentui.h"  #include "llclipboard.h" +#include "llfloaterreg.h"  #include "llfloatersidepanelcontainer.h"  #include "lllandmarkactions.h"  #include "lllocationinputctrl.h" @@ -456,7 +457,7 @@ void LLPanelTopInfoBar::onContextMenuItemClicked(const LLSD::String& item)  		if(landmark == NULL)  		{ -			LLFloaterSidePanelContainer::showPanel("places", LLSD().with("type", "create_landmark")); +			LLFloaterReg::showInstance("add_landmark");  		}  		else  		{ diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp index 4c539ded38..f13910cde5 100644 --- a/indra/newview/llpreviewscript.cpp +++ b/indra/newview/llpreviewscript.cpp @@ -636,14 +636,17 @@ bool LLScriptEdCore::writeToFile(const std::string& filename)  void LLScriptEdCore::sync()  { -	// Sync with external editor. -	std::string tmp_file = mContainer->getTmpFileName(); -	llstat s; -	if (LLFile::stat(tmp_file, &s) == 0) // file exists -	{ -		if (mLiveFile) mLiveFile->ignoreNextUpdate(); -		writeToFile(tmp_file); -	} +    // Sync with external editor. +    if (mLiveFile) +    { +        std::string tmp_file = mLiveFile->filename(); +        llstat s; +        if (LLFile::stat(tmp_file, &s) == 0) // file exists +        { +            mLiveFile->ignoreNextUpdate(); +            writeToFile(tmp_file); +        } +    }  }  bool LLScriptEdCore::hasChanged() @@ -1027,9 +1030,25 @@ void LLScriptEdCore::openInExternalEditor()  {  	delete mLiveFile; // deletes file -	// Save the script to a temporary file. -	std::string filename = mContainer->getTmpFileName(); -	writeToFile(filename); +	// Generate a suitable filename +    std::string script_name = mScriptName; +    std::string forbidden_chars = "<>:\"\\/|?*"; +    for (std::string::iterator c = forbidden_chars.begin(); c != forbidden_chars.end(); c++) +    { +        script_name.erase(std::remove(script_name.begin(), script_name.end(), *c), script_name.end()); +    } +	std::string filename = mContainer->getTmpFileName(script_name); + +    // Save the script to a temporary file. +    if (!writeToFile(filename)) +    { +        // In case some characters from script name are forbidden +        // and not accounted for, name is too long or some other issue, +        // try file that doesn't include script name +        script_name.clear(); +        filename = mContainer->getTmpFileName(script_name); +        writeToFile(filename); +    }  	// Start watching file changes.  	mLiveFile = new LLLiveLSLFile(filename, boost::bind(&LLScriptEdContainer::onExternalChange, mContainer, _1)); @@ -1419,7 +1438,7 @@ LLScriptEdContainer::LLScriptEdContainer(const LLSD& key) :  {  } -std::string LLScriptEdContainer::getTmpFileName() +std::string LLScriptEdContainer::getTmpFileName(const std::string& script_name)  {  	// Take script inventory item id (within the object inventory)  	// to consideration so that it's possible to edit multiple scripts @@ -1431,7 +1450,14 @@ std::string LLScriptEdContainer::getTmpFileName()  	LLMD5 script_id_hash((const U8 *)script_id.c_str());  	script_id_hash.hex_digest(script_id_hash_str); -	return std::string(LLFile::tmpdir()) + "sl_script_" + script_id_hash_str + ".lsl"; +    if (script_name.empty()) +    { +        return std::string(LLFile::tmpdir()) + "sl_script_" + script_id_hash_str + ".lsl"; +    } +    else +    { +        return std::string(LLFile::tmpdir()) + "sl_script_" + script_name + "_" + script_id_hash_str + ".lsl"; +    }  }  bool LLScriptEdContainer::onExternalChange(const std::string& filename) diff --git a/indra/newview/llpreviewscript.h b/indra/newview/llpreviewscript.h index 3cf22a0e6e..c1fea31063 100644 --- a/indra/newview/llpreviewscript.h +++ b/indra/newview/llpreviewscript.h @@ -205,7 +205,7 @@ public:  	LLScriptEdContainer(const LLSD& key, const bool live);  protected: -	std::string		getTmpFileName(); +	std::string		getTmpFileName(const std::string& script_name);  	bool			onExternalChange(const std::string& filename);  	virtual void	saveIfNeeded(bool sync = true) = 0; diff --git a/indra/newview/llsidepanelappearance.cpp b/indra/newview/llsidepanelappearance.cpp index 48151c17ea..6dfe40c29a 100644 --- a/indra/newview/llsidepanelappearance.cpp +++ b/indra/newview/llsidepanelappearance.cpp @@ -164,8 +164,12 @@ void LLSidepanelAppearance::onOpen(const LLSD& key)  		std::string type = key["type"].asString();  		if (type == "my_outfits")  		{ -			showOutfitsInventoryPanel(); +			showOutfitsInventoryPanel("outfitslist_tab");  		} +        else if (type == "now_wearing") +        { +            showOutfitsInventoryPanel("cof_tab"); +        }  		else if (type == "edit_outfit")  		{  			showOutfitEditPanel(); @@ -287,7 +291,14 @@ void LLSidepanelAppearance::showOutfitsInventoryPanel()  {  	toggleWearableEditPanel(FALSE);  	toggleOutfitEditPanel(FALSE); -	toggleMyOutfitsPanel(TRUE); +	toggleMyOutfitsPanel(TRUE, ""); +} + +void LLSidepanelAppearance::showOutfitsInventoryPanel(const std::string &tab_name) +{ +    toggleWearableEditPanel(FALSE); +    toggleOutfitEditPanel(FALSE); +    toggleMyOutfitsPanel(TRUE, tab_name);  }  void LLSidepanelAppearance::showOutfitEditPanel() @@ -312,37 +323,42 @@ void LLSidepanelAppearance::showOutfitEditPanel()  		return;  	} -	toggleMyOutfitsPanel(FALSE); +	toggleMyOutfitsPanel(FALSE, "");  	toggleWearableEditPanel(FALSE, NULL, TRUE); // don't switch out of edit appearance mode  	toggleOutfitEditPanel(TRUE);  }  void LLSidepanelAppearance::showWearableEditPanel(LLViewerWearable *wearable /* = NULL*/, BOOL disable_camera_switch)  { -	toggleMyOutfitsPanel(FALSE); +	toggleMyOutfitsPanel(FALSE, "");  	toggleOutfitEditPanel(FALSE, TRUE); // don't switch out of edit appearance mode  	toggleWearableEditPanel(TRUE, wearable, disable_camera_switch);  } -void LLSidepanelAppearance::toggleMyOutfitsPanel(BOOL visible) +void LLSidepanelAppearance::toggleMyOutfitsPanel(BOOL visible, const std::string& tab_name)  { -	if (!mPanelOutfitsInventory || mPanelOutfitsInventory->getVisible() == visible) -	{ -		// visibility isn't changing, hence nothing to do -		return; -	} - -	mPanelOutfitsInventory->setVisible(visible); - -	// *TODO: Move these controls to panel_outfits_inventory.xml -	// so that we don't need to toggle them explicitly. -	mFilterEditor->setVisible(visible); -	mCurrOutfitPanel->setVisible(visible); - -	if (visible) -	{ -		mPanelOutfitsInventory->onOpen(LLSD()); -	} +    if (!mPanelOutfitsInventory +        || (mPanelOutfitsInventory->getVisible() == visible && tab_name.empty())) +    { +        // visibility isn't changing, hence nothing to do +        return; +    } + +    mPanelOutfitsInventory->setVisible(visible); + +    // *TODO: Move these controls to panel_outfits_inventory.xml +    // so that we don't need to toggle them explicitly. +    mFilterEditor->setVisible(visible); +    mCurrOutfitPanel->setVisible(visible); + +    if (visible) +    { +        mPanelOutfitsInventory->onOpen(LLSD()); +        if (!tab_name.empty()) +        { +            mPanelOutfitsInventory->openApearanceTab(tab_name); +        } +    }  }  void LLSidepanelAppearance::toggleOutfitEditPanel(BOOL visible, BOOL disable_camera_switch) diff --git a/indra/newview/llsidepanelappearance.h b/indra/newview/llsidepanelappearance.h index 7817fd317c..bb9709a2b8 100644 --- a/indra/newview/llsidepanelappearance.h +++ b/indra/newview/llsidepanelappearance.h @@ -56,7 +56,8 @@ public:  	void fetchInventory();  	void inventoryFetched(); -	void showOutfitsInventoryPanel(); +    void showOutfitsInventoryPanel(); // last selected +	void showOutfitsInventoryPanel(const std::string& tab_name);  	void showOutfitEditPanel();  	void showWearableEditPanel(LLViewerWearable *wearable = NULL, BOOL disable_camera_switch = FALSE);  	void setWearablesLoading(bool val); @@ -72,7 +73,7 @@ private:  	void onOpenOutfitButtonClicked();  	void onEditAppearanceButtonClicked(); -	void toggleMyOutfitsPanel(BOOL visible); +	void toggleMyOutfitsPanel(BOOL visible, const std::string& tab_name);  	void toggleOutfitEditPanel(BOOL visible, BOOL disable_camera_switch = FALSE);  	void toggleWearableEditPanel(BOOL visible, LLViewerWearable* wearable = NULL, BOOL disable_camera_switch = FALSE); diff --git a/indra/newview/llskinningutil.cpp b/indra/newview/llskinningutil.cpp index f325315933..e02b21f036 100644 --- a/indra/newview/llskinningutil.cpp +++ b/indra/newview/llskinningutil.cpp @@ -131,7 +131,12 @@ void LLSkinningUtil::initSkinningMatrixPalette(      initJointNums(const_cast<LLMeshSkinInfo*>(skin), avatar);      for (U32 j = 0; j < count; ++j)      { -        LLJoint *joint = avatar->getJoint(skin->mJointNums[j]); +        S32 joint_num = skin->mJointNums[j]; +        LLJoint *joint = NULL; +        if (joint_num >= 0 && joint_num < LL_CHARACTER_MAX_ANIMATED_JOINTS) +        { +            joint = avatar->getJoint(joint_num); +        }          llassert(joint);          if (joint)          { diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index bc66f05306..68d5fa9951 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -128,10 +128,12 @@  #include "llpanelpick.h"  #include "llpanelgrouplandmoney.h"  #include "llpanelgroupnotices.h" +#include "llparcel.h"  #include "llpreview.h"  #include "llpreviewscript.h"  #include "llproxy.h"  #include "llproductinforequest.h" +#include "llqueryflags.h"  #include "llselectmgr.h"  #include "llsky.h"  #include "llstatview.h" @@ -142,6 +144,7 @@  #include "lltoolmgr.h"  #include "lltrans.h"  #include "llui.h" +#include "lluiusage.h"  #include "llurldispatcher.h"  #include "llurlentry.h"  #include "llslurl.h" @@ -229,7 +232,6 @@ extern S32 gStartImageHeight;  static bool gGotUseCircuitCodeAck = false;  static std::string sInitialOutfit;  static std::string sInitialOutfitGender;	// "male" or "female" -static boost::signals2::connection sWearablesLoadedCon;  static bool gUseCircuitCallbackCalled = false; @@ -1670,8 +1672,20 @@ bool idle_startup()  	if (STATE_INVENTORY_SEND == LLStartUp::getStartupState())  	{  		display_startup(); + +        // request mute list +        LL_INFOS() << "Requesting Mute List" << LL_ENDL; +        LLMuteList::getInstance()->requestFromServer(gAgent.getID()); + +        // Get L$ and ownership credit information +        LL_INFOS() << "Requesting Money Balance" << LL_ENDL; +        LLStatusBar::sendMoneyBalanceRequest(); + +        display_startup(); +  		// Inform simulator of our language preference  		LLAgentLanguage::update(); +  		display_startup();  		// unpack thin inventory  		LLSD response = LLLoginInstance::getInstance()->getResponse(); @@ -1824,9 +1838,6 @@ bool idle_startup()  		display_startup(); -		//all categories loaded. lets create "My Favorites" category -		gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE,true); -  		// set up callbacks  		LL_INFOS() << "Registering Callbacks" << LL_ENDL;  		LLMessageSystem* msg = gMessageSystem; @@ -1838,14 +1849,6 @@ bool idle_startup()  		LLLandmark::registerCallbacks(msg);  		display_startup(); -		// request mute list -		LL_INFOS() << "Requesting Mute List" << LL_ENDL; -		LLMuteList::getInstance()->requestFromServer(gAgent.getID()); -		display_startup(); -		// Get L$ and ownership credit information -		LL_INFOS() << "Requesting Money Balance" << LL_ENDL; -		LLStatusBar::sendMoneyBalanceRequest(); -		display_startup();  		// request all group information  		LL_INFOS() << "Requesting Agent Data" << LL_ENDL;  		gAgent.sendAgentDataUpdateRequest(); @@ -1902,10 +1905,6 @@ bool idle_startup()  			// Set the show start location to true, now that the user has logged  			// on with this install.  			gSavedSettings.setBOOL("ShowStartLocation", TRUE); - -			// Open Conversation floater on first login. -			LLFloaterReg::toggleInstanceOrBringToFront("im_container"); -  		}  		display_startup(); @@ -2263,6 +2262,16 @@ bool idle_startup()  		gAgentAvatarp->sendHoverHeight(); +		// look for parcels we own +		send_places_query(LLUUID::null, +			LLUUID::null, +			"", +			DFQ_AGENT_OWNED, +			LLParcel::C_ANY, +			""); + +		LLUIUsage::instance().clear(); +  		return TRUE;  	} @@ -2697,11 +2706,6 @@ void LLStartUp::loadInitialOutfit( const std::string& outfit_folder_name,  	}  	else  	{ -		// FIXME SH-3860 - this creates a race condition, where COF -		// changes (base outfit link added) after appearance update -		// request has been submitted. -		sWearablesLoadedCon = gAgentWearables.addLoadedCallback(LLStartUp::saveInitialOutfit); -  		bool do_copy = true;  		bool do_append = false;  		LLViewerInventoryCategory *cat = gInventory.getCategory(cat_id); @@ -2715,23 +2719,6 @@ void LLStartUp::loadInitialOutfit( const std::string& outfit_folder_name,  	gAgentWearables.sendDummyAgentWearablesUpdate();  } -//static -void LLStartUp::saveInitialOutfit() -{ -	if (sInitialOutfit.empty()) { -		LL_DEBUGS() << "sInitialOutfit is empty" << LL_ENDL; -		return; -	} -	 -	if (sWearablesLoadedCon.connected()) -	{ -		LL_DEBUGS("Avatar") << "sWearablesLoadedCon is connected, disconnecting" << LL_ENDL; -		sWearablesLoadedCon.disconnect(); -	} -	LL_DEBUGS("Avatar") << "calling makeNewOutfitLinks( \"" << sInitialOutfit << "\" )" << LL_ENDL; -	LLAppearanceMgr::getInstance()->makeNewOutfitLinks(sInitialOutfit,false); -} -  std::string& LLStartUp::getInitialOutfitName()  {  	return sInitialOutfit; diff --git a/indra/newview/llstartup.h b/indra/newview/llstartup.h index 3ec3ff4133..116aeb36a7 100644 --- a/indra/newview/llstartup.h +++ b/indra/newview/llstartup.h @@ -110,9 +110,6 @@ public:  	static void loadInitialOutfit( const std::string& outfit_folder_name,  								   const std::string& gender_name ); -	//save loaded initial outfit into My Outfits category -	static void saveInitialOutfit(); -  	static std::string& getInitialOutfitName();  	static std::string getUserId(); diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp index 4d55448d78..0a87b14e17 100644 --- a/indra/newview/llstatusbar.cpp +++ b/indra/newview/llstatusbar.cpp @@ -416,7 +416,20 @@ void LLStatusBar::sendMoneyBalanceRequest()  	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());  	msg->nextBlockFast(_PREHASH_MoneyData);  	msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null ); -	gAgent.sendReliableMessage(); + +    if (gDisconnected) +    { +        LL_DEBUGS() << "Trying to send message when disconnected, skipping balance request!" << LL_ENDL; +        return; +    } +    if (!gAgent.getRegion()) +    { +        LL_DEBUGS() << "LLAgent::sendReliableMessage No region for agent yet, skipping balance request!" << LL_ENDL; +        return; +    } +    // Double amount of retries due to this request initially happening during busy stage +    // Ideally this should be turned into a capability +    gMessageSystem->sendReliable(gAgent.getRegionHost(), LL_DEFAULT_RELIABLE_RETRIES * 2, TRUE, LL_PING_BASED_TIMEOUT_DUMMY, NULL, NULL);  } diff --git a/indra/newview/llteleporthistorystorage.cpp b/indra/newview/llteleporthistorystorage.cpp index 8a5704939a..7d4988c0cc 100644 --- a/indra/newview/llteleporthistorystorage.cpp +++ b/indra/newview/llteleporthistorystorage.cpp @@ -33,6 +33,8 @@  #include "lldir.h"  #include "llteleporthistory.h"  #include "llagent.h" +#include "llfloaterreg.h" +#include "llfloaterworldmap.h"  // Max offset for two global positions to consider them as equal  const F64 MAX_GLOBAL_POS_OFFSET = 5.0f; @@ -201,6 +203,12 @@ void LLTeleportHistoryStorage::load()  	std::string line;  	while (std::getline(file, line))  	{ +		if (line.empty()) +		{ +			LL_WARNS() << "Teleport history contains empty line."<< LL_ENDL; +			continue; +		} +		  		LLSD s_item;  		std::istringstream iss(line);  		if (parser->parse(iss, s_item, line.length()) == LLSDParser::PARSE_FAILURE) @@ -253,3 +261,23 @@ void LLTeleportHistoryStorage::goToItem(S32 idx)  	gAgent.teleportViaLocation(mItems[idx].mGlobalPos);  } +void LLTeleportHistoryStorage::showItemOnMap(S32 idx) +{ +    // Validate specified index. +    if (idx < 0 || idx >= (S32)mItems.size()) +    { +        LL_WARNS() << "Invalid teleport history index (" << idx << ") specified" << LL_ENDL; +        dump(); +        return; +    } + +    LLVector3d landmark_global_pos = mItems[idx].mGlobalPos; + +    LLFloaterWorldMap* worldmap_instance = LLFloaterWorldMap::getInstance(); +    if (!landmark_global_pos.isExactlyZero() && worldmap_instance) +    { +        worldmap_instance->trackLocation(landmark_global_pos); +        LLFloaterReg::showInstance("world_map", "center"); +    } +} + diff --git a/indra/newview/llteleporthistorystorage.h b/indra/newview/llteleporthistorystorage.h index 946ac0af1a..3578923fd7 100644 --- a/indra/newview/llteleporthistorystorage.h +++ b/indra/newview/llteleporthistorystorage.h @@ -107,6 +107,13 @@ public:  	 */  	void					goToItem(S32 idx); +    /** +     * Show specific item on map. +     * +     * The item is specified by its index (starting from 0). +     */ +    void					showItemOnMap(S32 idx); +  private:  	void load(); diff --git a/indra/newview/lltoastalertpanel.cpp b/indra/newview/lltoastalertpanel.cpp index 6a29be4aa1..8baad30e8f 100644 --- a/indra/newview/lltoastalertpanel.cpp +++ b/indra/newview/lltoastalertpanel.cpp @@ -121,6 +121,11 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal  				data.mURLExternal = mNotification->getURLOpenExternally();  			} +			if((*it).has("width")) +			{ +				data.mWidth = (*it)["width"].asInteger(); +			} +  			mButtonData.push_back(data);  			option_index++;  		} @@ -159,15 +164,29 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal  	// Calc total width of buttons  	S32 button_width = 0;  	S32 sp = font->getWidth(std::string("OO")); +	S32 btn_total_width = 0; +	S32 default_size_btns = 0;  	for( S32 i = 0; i < num_options; i++ ) -	{ +	{				  		S32 w = S32(font->getWidth( options[i].second ) + 0.99f) + sp + 2 * LLBUTTON_H_PAD; -		button_width = llmax( w, button_width ); +		if (mButtonData[i].mWidth > w) +		{ +			btn_total_width += mButtonData[i].mWidth; +		} +		else +		{ +			button_width = llmax(w, button_width); +			default_size_btns++; +		}  	} -	S32 btn_total_width = button_width; +  	if( num_options > 1 )  	{ -		btn_total_width = (num_options * button_width) + ((num_options - 1) * BTN_HPAD); +		btn_total_width = btn_total_width + (button_width * default_size_btns) + ((num_options - 1) * BTN_HPAD); +	} +	else +	{ +		btn_total_width = llmax(btn_total_width, button_width);  	}  	// Message: create text box using raw string, as text has been structure deliberately @@ -272,7 +291,7 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal  			mLineEditor->setText(edit_text_contents);  			std::string notif_name = mNotification->getName(); -			if (("SaveOutfitAs" == notif_name) || ("SaveSettingAs" == notif_name)) +			if (("SaveOutfitAs" == notif_name) || ("SaveSettingAs" == notif_name) || ("CreateLandmarkFolder" == notif_name))  			{  				mLineEditor->setPrevalidate(&LLTextValidate::validateASCII);  			} @@ -333,7 +352,7 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal  		if(btn)  		{  			btn->setName(options[i].first); -			btn->setRect(button_rect.setOriginAndSize( button_left, VPAD, button_width, BTN_HEIGHT )); +			btn->setRect(button_rect.setOriginAndSize( button_left, VPAD, (mButtonData[i].mWidth == 0) ? button_width : mButtonData[i].mWidth, BTN_HEIGHT ));  			btn->setLabel(options[i].second);  			btn->setFont(font); @@ -348,7 +367,7 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal  				btn->setFocus(TRUE);  			}  		} -		button_left += button_width + BTN_HPAD; +		button_left += ((mButtonData[i].mWidth == 0) ? button_width : mButtonData[i].mWidth) + BTN_HPAD;  	}  	setCheckBoxes(HPAD, VPAD); diff --git a/indra/newview/lltoastalertpanel.h b/indra/newview/lltoastalertpanel.h index 9b4e054bf1..bd34e40642 100644 --- a/indra/newview/lltoastalertpanel.h +++ b/indra/newview/lltoastalertpanel.h @@ -82,9 +82,14 @@ private:  	struct ButtonData  	{ +		ButtonData() +		: mWidth(0) +		{} +		  		LLButton* mButton;  		std::string mURL;  		U32 mURLExternal; +		S32 mWidth;  	};  	std::vector<ButtonData> mButtonData; diff --git a/indra/newview/lltoastnotifypanel.cpp b/indra/newview/lltoastnotifypanel.cpp index bccf88128d..024f25bc98 100644 --- a/indra/newview/lltoastnotifypanel.cpp +++ b/indra/newview/lltoastnotifypanel.cpp @@ -387,9 +387,9 @@ void LLToastNotifyPanel::init( LLRect rect, bool show_images )              if (mIsScriptDialog)              {                  // we are using default width for script buttons so we can determinate button_rows -                //to get a number of rows we divide the required width of the buttons to button_panel_width -                S32 button_rows = llceil(F32(buttons.size() - 1) * (BUTTON_WIDTH + h_pad) / button_panel_width); -                //S32 button_rows = (buttons.size() - 1) * (BUTTON_WIDTH + h_pad) / button_panel_width; +                // to get a number of rows we divide the required width of the buttons to button_panel_width +                // buttons.size() is reduced by -2 due to presence of ignore button which is calculated independently a bit lower +                S32 button_rows = llceil(F32(buttons.size() - 2) * (BUTTON_WIDTH + h_pad) / (button_panel_width + h_pad));                  //reserve one row for the ignore_btn                  button_rows++;                  //calculate required panel height for scripdialog notification. diff --git a/indra/newview/lltoolmgr.cpp b/indra/newview/lltoolmgr.cpp index 3fcf193dec..fa2dd60ee0 100644 --- a/indra/newview/lltoolmgr.cpp +++ b/indra/newview/lltoolmgr.cpp @@ -405,7 +405,7 @@ void LLToolMgr::clearTransientTool()  void LLToolMgr::onAppFocusLost()  { -	if (LLApp::isQuitting()) +	if (LLApp::isExiting())  		return;  	if (mSelectedTool) diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp index 322d0bc727..75a5fabdc2 100644 --- a/indra/newview/lltoolpie.cpp +++ b/indra/newview/lltoolpie.cpp @@ -1234,7 +1234,8 @@ BOOL LLToolPie::handleTooltipObject( LLViewerObject* hover_object, std::string l  BOOL LLToolPie::handleToolTip(S32 local_x, S32 local_y, MASK mask)  { -	if (!LLUI::getInstance()->mSettingGroups["config"]->getBOOL("ShowHoverTips")) return TRUE; +	static LLCachedControl<bool> show_hover_tips(*LLUI::getInstance()->mSettingGroups["config"], "ShowHoverTips", true); +	if (!show_hover_tips) return TRUE;  	if (!mHoverPick.isValid()) return TRUE;  	LLViewerObject* hover_object = mHoverPick.getObject(); diff --git a/indra/newview/lltranslate.cpp b/indra/newview/lltranslate.cpp index fa3b44f702..553a3cd086 100644 --- a/indra/newview/lltranslate.cpp +++ b/indra/newview/lltranslate.cpp @@ -144,6 +144,7 @@ void LLTranslationAPIHandler::verifyKeyCoro(LLTranslate::EService service, std::      httpHeaders->append(HTTP_OUT_HEADER_USER_AGENT, user_agent);      httpOpts->setFollowRedirects(true); +    httpOpts->setSSLVerifyPeer(false);      std::string url = this->getKeyVerificationURL(key);      if (url.empty()) @@ -185,6 +186,7 @@ void LLTranslationAPIHandler::translateMessageCoro(LanguagePair_t fromTo, std::s      httpHeaders->append(HTTP_OUT_HEADER_ACCEPT, HTTP_CONTENT_TEXT_PLAIN);      httpHeaders->append(HTTP_OUT_HEADER_USER_AGENT, user_agent); +    httpOpts->setSSLVerifyPeer(false);      std::string url = this->getTranslateURL(fromTo.first, fromTo.second, msg);      if (url.empty()) diff --git a/indra/newview/llurlfloaterdispatchhandler.cpp b/indra/newview/llurlfloaterdispatchhandler.cpp new file mode 100644 index 0000000000..6b1a373beb --- /dev/null +++ b/indra/newview/llurlfloaterdispatchhandler.cpp @@ -0,0 +1,214 @@ +/**  + * @file llurlfloaterdispatchhandler.cpp + * @brief Handles URLFloater generic message from server + * + * $LicenseInfo:firstyear=2021&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2021, 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 "llurlfloaterdispatchhandler.h" + +#include "llfloaterreg.h" +#include "llfloaterhowto.h" +#include "llfloaterwebcontent.h" +#include "llsdserialize.h" +#include "llviewercontrol.h" +#include "llviewergenericmessage.h" +#include "llweb.h" + +// Example: +// llOpenFloater("guidebook", "http://page.com", []); + +// values specified by server side's dispatcher +// for llopenfloater +const std::string MESSAGE_URL_FLOATER("URLFloater"); +const std::string KEY_ACTION("action"); // "action" will be the string constant "OpenURL" +const std::string VALUE_OPEN_URL("OpenURL"); +const std::string KEY_DATA("action_data"); +const std::string KEY_FLOATER("floater_title"); // name of the floater, not title +const std::string KEY_URL("floater_url"); +const std::string KEY_PARAMS("floater_params"); + +// Supported floaters +const std::string FLOATER_GUIDEBOOK("guidebook"); +const std::string FLOATER_HOW_TO("how_to"); // alias for guidebook +const std::string FLOATER_WEB_CONTENT("web_content"); + +// All arguments are palceholders! Server side will need to add validation first. +// Web content universal argument +const std::string KEY_TRUSTED_CONTENT("trusted_content"); + +// Guidebook specific arguments +const std::string KEY_WIDTH("width"); +const std::string KEY_HEGHT("height"); +const std::string KEY_CAN_CLOSE("can_close"); +const std::string KEY_TITLE("title"); + +// web_content specific arguments +const std::string KEY_SHOW_PAGE_TITLE("show_page_title"); +const std::string KEY_ALLOW_ADRESS_ENTRY("allow_address_entry"); // It is not recomended to set this to true if trusted content is allowed + + +LLUrlFloaterDispatchHandler LLUrlFloaterDispatchHandler::sUrlDispatchhandler; + +LLUrlFloaterDispatchHandler::LLUrlFloaterDispatchHandler() +{ +} + +LLUrlFloaterDispatchHandler::~LLUrlFloaterDispatchHandler() +{ +} + +void LLUrlFloaterDispatchHandler::registerInDispatcher() +{ +    if (!gGenericDispatcher.isHandlerPresent(MESSAGE_URL_FLOATER)) +    { +        gGenericDispatcher.addHandler(MESSAGE_URL_FLOATER, &sUrlDispatchhandler); +    } +} + +//virtual +bool LLUrlFloaterDispatchHandler::operator()(const LLDispatcher *, const std::string& key, const LLUUID& invoice, const sparam_t& strings) +{ +    // invoice - transaction id + +    LLSD message; +    sparam_t::const_iterator it = strings.begin(); + +    if (it != strings.end()) +    { +        const std::string& llsdRaw = *it++; +        std::istringstream llsdData(llsdRaw); +        if (!LLSDSerialize::deserialize(message, llsdData, llsdRaw.length())) +        { +            LL_WARNS("URLFloater") << "Attempted to read parameter data into LLSD but failed:" << llsdRaw << LL_ENDL; +            return false; +        } +    } + +    // At the moment command_params is a placeholder and code treats it as map +    // Once server side adds argument validation this will be either a map or an array +    std::string floater; +    LLSD command_params; +    std::string url; + +    if (message.has(KEY_ACTION) && message[KEY_ACTION].asString() == VALUE_OPEN_URL) +    { +        LLSD &action_data = message[KEY_DATA]; +        if (action_data.isMap()) +        { +            floater = action_data[KEY_FLOATER].asString(); +            command_params = action_data[KEY_PARAMS]; +            url = action_data[KEY_URL].asString(); +        } +    } +    else if (message.has(KEY_FLOATER)) +    { +        floater = message[KEY_FLOATER].asString(); +        command_params = message[KEY_PARAMS]; +        url = message[KEY_URL].asString(); +    } +    else +    { +        LL_WARNS("URLFloater") << "Received " << MESSAGE_URL_FLOATER << " with unexpected data format: " << message << LL_ENDL; +        return false; +    } + +    if (url.find("://") == std::string::npos) +    { +        // try unescaping +        url = LLURI::unescape(url); +    } + +    LLFloaterWebContent::Params params; +    params.url = url; + +    if (floater == FLOATER_GUIDEBOOK || floater == FLOATER_HOW_TO) +    { +        LL_DEBUGS("URLFloater") << "Opening how_to floater with parameters: " << message << LL_ENDL; +        if (command_params.isMap()) // by default is undefines +        { +            params.trusted_content = command_params.has(KEY_TRUSTED_CONTENT) ? command_params[KEY_TRUSTED_CONTENT].asBoolean() : false; + +            // Script's side argument list can't include other lists, neither +            // there is a LLRect type, so expect just width and height +            if (command_params.has(KEY_WIDTH) && command_params.has(KEY_HEGHT)) +            { +                LLRect rect(0, command_params[KEY_HEGHT].asInteger(), command_params[KEY_WIDTH].asInteger(), 0); +                params.preferred_media_size.setValue(rect); +            } +        } + +        // Some locations will have customized guidebook, which this function easists for +        // only one instance of guidebook can exist at a time, so if this command arrives, +        // we need to close previous guidebook then reopen it. + +        LLFloater* instance = LLFloaterReg::findInstance("guidebook"); +        if (instance) +        { +            instance->closeHostedFloater(); +        } + +        LLFloaterReg::toggleInstanceOrBringToFront("guidebook", params); +         +        if (command_params.isMap()) +        { +            LLFloater* instance = LLFloaterReg::findInstance("guidebook"); +            if (command_params.has(KEY_CAN_CLOSE)) +            { +                instance->setCanClose(command_params[KEY_CAN_CLOSE].asBoolean()); +            } +            if (command_params.has(KEY_TITLE)) +            { +                instance->setTitle(command_params[KEY_TITLE].asString()); +            } +        } +    } +    else if (floater == FLOATER_WEB_CONTENT) +    { +        LL_DEBUGS("URLFloater") << "Opening web_content floater with parameters: " << message << LL_ENDL; +        if (command_params.isMap()) // by default is undefines, might be better idea to init params from command_params +        { +            params.trusted_content = command_params.has(KEY_TRUSTED_CONTENT) ? command_params[KEY_TRUSTED_CONTENT].asBoolean() : false; +            params.show_page_title = command_params.has(KEY_SHOW_PAGE_TITLE) ? command_params[KEY_SHOW_PAGE_TITLE].asBoolean() : true; +            params.allow_address_entry = command_params.has(KEY_ALLOW_ADRESS_ENTRY) ? command_params[KEY_ALLOW_ADRESS_ENTRY].asBoolean() : true; +        } +        LLFloaterReg::showInstance("web_content", params); +    } +    else +    { +        LL_DEBUGS("URLFloater") << "Unknow floater with parameters: " << message << LL_ENDL; +        if (LLFloaterReg::isRegistered(floater)) +        { +            // A valid floater +            LL_INFOS("URLFloater") << "Floater " << floater << " is not supported by llopenfloater or URLFloater" << LL_ENDL; +        } +        else +        { +            // A valid message, but no such flaoter +            LL_WARNS("URLFloater") << "Recieved a command to open unknown floater: " << floater << LL_ENDL; +        } +    } + +    return true; +} diff --git a/indra/newview/llurlfloaterdispatchhandler.h b/indra/newview/llurlfloaterdispatchhandler.h new file mode 100644 index 0000000000..1dff52c66f --- /dev/null +++ b/indra/newview/llurlfloaterdispatchhandler.h @@ -0,0 +1,49 @@ +/**  + * @file llurlfloaterdispatchhandler.h + * @brief Handles URLFloater generic message from server + * + * $LicenseInfo:firstyear=2021&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2021, 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_LLURLFLOATERDISPATCHHANDLER_H +#define LL_LLURLFLOATERDISPATCHHANDLER_H + +#include "lldispatcher.h" + +class LLUrlFloaterDispatchHandler : public LLDispatchHandler +{ +public: +    LOG_CLASS(LLUrlFloaterDispatchHandler); + +    LLUrlFloaterDispatchHandler(); +    virtual ~LLUrlFloaterDispatchHandler(); + +    virtual bool operator()(const LLDispatcher *, const std::string& key, const LLUUID& invoice, const sparam_t& strings) override; + +    static void registerInDispatcher(); + +private: +    static LLUrlFloaterDispatchHandler sUrlDispatchhandler; +}; + +#endif  // LL_LLURLFLOATERDISPATCHHANDLER_H + diff --git a/indra/newview/llviewerassetstorage.cpp b/indra/newview/llviewerassetstorage.cpp index 7842d24279..c1b129750a 100644 --- a/indra/newview/llviewerassetstorage.cpp +++ b/indra/newview/llviewerassetstorage.cpp @@ -115,6 +115,7 @@ LLViewerAssetStorage::LLViewerAssetStorage(LLMessageSystem *msg, LLXferManager *        mCountSucceeded(0),        mTotalBytesFetched(0)  { +    LLCoprocedureManager::instance().initializePool(VIEWER_ASSET_STORAGE_CORO_POOL);  } @@ -128,6 +129,7 @@ LLViewerAssetStorage::LLViewerAssetStorage(LLMessageSystem *msg, LLXferManager *        mCountSucceeded(0),        mTotalBytesFetched(0)  { +    LLCoprocedureManager::instance().initializePool(VIEWER_ASSET_STORAGE_CORO_POOL);  }  LLViewerAssetStorage::~LLViewerAssetStorage() @@ -544,7 +546,7 @@ void LLViewerAssetStorage::assetRequestCoro(      LLSD result = httpAdapter->getRawAndSuspend(httpRequest, url, httpOpts); -    if (LLApp::isQuitting() || !gAssetStorage) +    if (LLApp::isExiting() || !gAssetStorage)      {          // Bail out if result arrives after shutdown has been started.          return; diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 6d939fbe21..109dc93261 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -474,6 +474,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)  			gAgent.setTeleportState( LLAgent::TELEPORT_ARRIVING );  			gAgent.setTeleportMessage(  				LLAgent::sTeleportProgressMessages["arriving"]); +			gAgent.sheduleTeleportIM();  			gTextureList.mForceResetTextureStats = TRUE;  			gAgentCamera.resetView(TRUE, TRUE); @@ -1498,10 +1499,9 @@ void render_ui_2d()  	if (gSavedSettings.getBOOL("RenderUIBuffer"))  	{ -		LLUI* ui_inst = LLUI::getInstance(); -		if (ui_inst->mDirty) +		if (LLView::sIsRectDirty)  		{ -			ui_inst->mDirty = FALSE; +            LLView::sIsRectDirty = false;  			LLRect t_rect;  			gPipeline.mUIScreen.bindTarget(); @@ -1509,25 +1509,25 @@ void render_ui_2d()  			{  				static const S32 pad = 8; -				ui_inst->mDirtyRect.mLeft -= pad; -				ui_inst->mDirtyRect.mRight += pad; -				ui_inst->mDirtyRect.mBottom -= pad; -				ui_inst->mDirtyRect.mTop += pad; +                LLView::sDirtyRect.mLeft -= pad; +                LLView::sDirtyRect.mRight += pad; +                LLView::sDirtyRect.mBottom -= pad; +                LLView::sDirtyRect.mTop += pad;  				LLGLEnable scissor(GL_SCISSOR_TEST); -				static LLRect last_rect = ui_inst->mDirtyRect; +				static LLRect last_rect = LLView::sDirtyRect;  				//union with last rect to avoid mouse poop -				last_rect.unionWith(ui_inst->mDirtyRect); +				last_rect.unionWith(LLView::sDirtyRect); -				t_rect = ui_inst->mDirtyRect; -				ui_inst->mDirtyRect = last_rect; +				t_rect = LLView::sDirtyRect; +                LLView::sDirtyRect = last_rect;  				last_rect = t_rect; -			 -				last_rect.mLeft = LLRect::tCoordType(last_rect.mLeft / ui_inst->getScaleFactor().mV[0]); -				last_rect.mRight = LLRect::tCoordType(last_rect.mRight / ui_inst->getScaleFactor().mV[0]); -				last_rect.mTop = LLRect::tCoordType(last_rect.mTop / ui_inst->getScaleFactor().mV[1]); -				last_rect.mBottom = LLRect::tCoordType(last_rect.mBottom / ui_inst->getScaleFactor().mV[1]); + +				last_rect.mLeft = LLRect::tCoordType(last_rect.mLeft / LLUI::getScaleFactor().mV[0]); +				last_rect.mRight = LLRect::tCoordType(last_rect.mRight / LLUI::getScaleFactor().mV[0]); +				last_rect.mTop = LLRect::tCoordType(last_rect.mTop / LLUI::getScaleFactor().mV[1]); +				last_rect.mBottom = LLRect::tCoordType(last_rect.mBottom / LLUI::getScaleFactor().mV[1]);  				LLRect clip_rect(last_rect); @@ -1539,7 +1539,7 @@ void render_ui_2d()  			gPipeline.mUIScreen.flush();  			gGL.setColorMask(true, false); -			ui_inst->mDirtyRect = t_rect; +            LLView::sDirtyRect = t_rect;  		}  		LLGLDisable cull(GL_CULL_FACE); diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index 4ae4cee31d..67f1f5c65c 100644 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -34,6 +34,7 @@  #include "llcompilequeue.h"  #include "llfasttimerview.h"  #include "llfloaterabout.h" +#include "llfloateraddpaymentmethod.h"  #include "llfloaterauction.h"  #include "llfloaterautoreplacesettings.h"  #include "llfloateravatar.h" @@ -57,6 +58,7 @@  #include "llfloaterchatvoicevolume.h"  #include "llfloaterconversationlog.h"  #include "llfloaterconversationpreview.h" +#include "llfloatercreatelandmark.h"  #include "llfloaterdeleteprefpreset.h"  #include "llfloaterdestinations.h"  #include "llfloaterdisplayname.h" @@ -75,6 +77,7 @@  #include "llfloatergroups.h"  #include "llfloaterhelpbrowser.h"  #include "llfloaterhoverheight.h" +#include "llfloaterhowto.h"  #include "llfloaterhud.h"  #include "llfloaterimagepreview.h"  #include "llfloaterimsession.h" @@ -195,6 +198,7 @@ void LLViewerFloaterReg::registerFloaters()  	LLFloaterAboutUtil::registerFloater();  	LLFloaterReg::add("block_timers", "floater_fast_timers.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFastTimerView>);  	LLFloaterReg::add("about_land", "floater_about_land.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterLand>); +	LLFloaterReg::add("add_payment_method", "floater_add_payment_method.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAddPaymentMethod>);  	LLFloaterReg::add("appearance", "floater_my_appearance.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSidePanelContainer>);  	LLFloaterReg::add("associate_listing", "floater_associate_listing.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAssociateListing>);  	LLFloaterReg::add("auction", "floater_auction.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAuction>); @@ -221,6 +225,7 @@ void LLViewerFloaterReg::registerFloaters()  	LLFloaterReg::add("nearby_chat", "floater_im_session.xml", (LLFloaterBuildFunc)&LLFloaterIMNearbyChat::buildFloater);  	LLFloaterReg::add("compile_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCompileQueue>);  	LLFloaterReg::add("conversation", "floater_conversation_log.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterConversationLog>); +	LLFloaterReg::add("add_landmark", "floater_create_landmark.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCreateLandmark>);  	LLFloaterReg::add("delete_pref_preset", "floater_delete_pref_preset.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterDeletePrefPreset>);  	LLFloaterReg::add("destinations", "floater_destinations.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterDestinations>); @@ -359,7 +364,7 @@ void LLViewerFloaterReg::registerFloaters()      LLFloaterReg::add("outfit_snapshot", "floater_outfit_snapshot.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterOutfitSnapshot>);      LLFloaterReg::add("search", "floater_search.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSearch>);      LLFloaterReg::add("profile", "floater_profile.xml",(LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterProfile>); -	LLFloaterReg::add("how_to", "floater_how_to.xml", (LLFloaterBuildFunc)&LLFloaterWebContent::create); +	LLFloaterReg::add("guidebook", "floater_how_to.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterHowTo>);  	LLFloaterReg::add("big_preview", "floater_big_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterBigPreview>); diff --git a/indra/newview/llviewerfoldertype.cpp b/indra/newview/llviewerfoldertype.cpp index afa84a5afc..f770db31dd 100644 --- a/indra/newview/llviewerfoldertype.cpp +++ b/indra/newview/llviewerfoldertype.cpp @@ -130,7 +130,7 @@ LLViewerFolderDictionary::LLViewerFolderDictionary()  	addEntry(LLFolderType::FT_FAVORITE, 			new ViewerFolderEntry("Favorites",				"Inv_SysOpen",			"Inv_SysClosed",		FALSE,     true));  	addEntry(LLFolderType::FT_CURRENT_OUTFIT, 		new ViewerFolderEntry("Current Outfit",			"Inv_SysOpen",			"Inv_SysClosed",		TRUE,      false)); -	addEntry(LLFolderType::FT_OUTFIT, 				new ViewerFolderEntry("New Outfit",				"Inv_LookFolderOpen",	"Inv_LookFolderClosed",	TRUE,      true)); +	addEntry(LLFolderType::FT_OUTFIT, 				new ViewerFolderEntry("New Outfit",				"Inv_LookFolderOpen",	"Inv_LookFolderClosed",	TRUE,      false));  	addEntry(LLFolderType::FT_MY_OUTFITS, 			new ViewerFolderEntry("My Outfits",				"Inv_SysOpen",			"Inv_SysClosed",		TRUE,      true));  	addEntry(LLFolderType::FT_MESH, 				new ViewerFolderEntry("Meshes",					"Inv_SysOpen",			"Inv_SysClosed",		FALSE,     true));  	addEntry(LLFolderType::FT_SETTINGS, 		    new ViewerFolderEntry("Settings",			    "Inv_SysOpen",			"Inv_SysClosed",		FALSE,     true)); diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index 13afffcfa7..41b64d1864 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -1237,6 +1237,7 @@ void LLViewerMedia::getOpenIDCookieCoro(std::string url)      httpOpts->setFollowRedirects(true);      httpOpts->setWantHeaders(true); +    httpOpts->setSSLVerifyPeer(false); // viewer's cert bundle doesn't appear to agree with web certs from "https://my.secondlife.com/"      LLURL hostUrl(url.c_str());      std::string hostAuth = hostUrl.getAuthority(); diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 8490b0f6ed..e5bccaab36 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -64,6 +64,7 @@  #include "llfloaterimcontainer.h"  #include "llfloaterland.h"  #include "llfloaterimnearbychat.h" +#include "llfloaterlandholdings.h"  #include "llfloaterpathfindingcharacters.h"  #include "llfloaterpathfindinglinksets.h"  #include "llfloaterpay.h" @@ -185,11 +186,15 @@ const std::string SAVE_INTO_TASK_INVENTORY("Save Object Back to Object Contents"  LLMenuGL* gAttachSubMenu = NULL;  LLMenuGL* gDetachSubMenu = NULL;  LLMenuGL* gTakeOffClothes = NULL; +LLMenuGL* gDetachAvatarMenu = NULL; +LLMenuGL* gDetachHUDAvatarMenu = NULL;  LLContextMenu* gAttachScreenPieMenu = NULL;  LLContextMenu* gAttachPieMenu = NULL;  LLContextMenu* gAttachBodyPartPieMenus[9];  LLContextMenu* gDetachPieMenu = NULL;  LLContextMenu* gDetachScreenPieMenu = NULL; +LLContextMenu* gDetachAttSelfMenu = NULL; +LLContextMenu* gDetachHUDAttSelfMenu = NULL;  LLContextMenu* gDetachBodyPartPieMenus[9];  // @@ -286,6 +291,8 @@ void force_error_bad_memory_access(void *);  void force_error_infinite_loop(void *);  void force_error_software_exception(void *);  void force_error_driver_crash(void *); +void force_error_coroutine_crash(void *); +void force_error_thread_crash(void *);  void handle_force_delete(void*);  void print_object_info(void*); @@ -444,6 +451,9 @@ void init_menus()  	gMenuAttachmentOther = LLUICtrlFactory::createFromFile<LLContextMenu>(  		"menu_attachment_other.xml", gMenuHolder, registry); +	gDetachHUDAttSelfMenu = gMenuHolder->getChild<LLContextMenu>("Detach Self HUD", true); +	gDetachAttSelfMenu = gMenuHolder->getChild<LLContextMenu>("Detach Self", true); +  	gMenuLand = LLUICtrlFactory::createFromFile<LLContextMenu>(  		"menu_land.xml", gMenuHolder, registry); @@ -500,6 +510,9 @@ void init_menus()  	gAttachSubMenu = gMenuBarView->findChildMenuByName("Attach Object", TRUE);  	gDetachSubMenu = gMenuBarView->findChildMenuByName("Detach Object", TRUE); +	gDetachAvatarMenu = gMenuHolder->getChild<LLMenuGL>("Avatar Detach", true); +	gDetachHUDAvatarMenu = gMenuHolder->getChild<LLMenuGL>("Avatar Detach HUD", true); +  	// Don't display the Memory console menu if the feature is turned off  	LLMenuItemCheckGL *memoryMenu = gMenuBarView->getChild<LLMenuItemCheckGL>("Memory", TRUE);  	if (memoryMenu) @@ -676,19 +689,6 @@ class LLAdvancedCheckHUDInfo : public view_listener_t  }; -////////////// -// FLYING   // -////////////// - -class LLAdvancedAgentFlyingInfo : public view_listener_t -{ -	bool handleEvent(const LLSD&) -	{ -		return gAgent.getFlying(); -	} -}; - -  ///////////////////////  // CLEAR GROUP CACHE //  /////////////////////// @@ -2363,6 +2363,24 @@ class LLAdvancedForceErrorDriverCrash : public view_listener_t  	}  }; +class LLAdvancedForceErrorCoroutineCrash : public view_listener_t +{ +    bool handleEvent(const LLSD& userdata) +    { +        force_error_coroutine_crash(NULL); +        return true; +    } +}; + +class LLAdvancedForceErrorThreadCrash : public view_listener_t +{ +    bool handleEvent(const LLSD& userdata) +    { +        force_error_thread_crash(NULL); +        return true; +    } +}; +  class LLAdvancedForceErrorDisconnectViewer : public view_listener_t  {  	bool handleEvent(const LLSD& userdata) @@ -3748,6 +3766,35 @@ bool enable_sitdown_self()  	return show_sitdown_self() && !gAgentAvatarp->isEditingAppearance() && !gAgent.getFlying();  } +class LLSelfToggleSitStand : public view_listener_t +{ +	bool handleEvent(const LLSD& userdata) +	{ +		if (isAgentAvatarValid()) +		{ +			if (gAgentAvatarp->isSitting()) +			{ +				gAgent.standUp(); +			} +			else +			{ +				gAgent.sitDown(); +			} +		} +		return true; +	} +}; + +bool enable_sit_stand() +{ +	return enable_sitdown_self() || enable_standup_self(); +} + +bool enable_fly_land() +{ +	return gAgent.getFlying() || LLAgent::enableFlying(); +} +  class LLCheckPanelPeopleTab : public view_listener_t  {  	bool handleEvent(const LLSD& userdata) @@ -4113,25 +4160,31 @@ void near_sit_down_point(BOOL success, void *)  class LLLandSit : public view_listener_t  { -	bool handleEvent(const LLSD& userdata) -	{ -		gAgent.standUp(); -		LLViewerParcelMgr::getInstance()->deselectLand(); +    bool handleEvent(const LLSD& userdata) +    { +        LLVector3d posGlobal = LLToolPie::getInstance()->getPick().mPosGlobal; -		LLVector3d posGlobal = LLToolPie::getInstance()->getPick().mPosGlobal; -		 -		LLQuaternion target_rot; -		if (isAgentAvatarValid()) -		{ -			target_rot = gAgentAvatarp->getRotation(); -		} -		else -		{ -			target_rot = gAgent.getFrameAgent().getQuaternion(); -		} -		gAgent.startAutoPilotGlobal(posGlobal, "Sit", &target_rot, near_sit_down_point, NULL, 0.7f); -		return true; -	} +        LLQuaternion target_rot; +        if (isAgentAvatarValid()) +        { +            target_rot = gAgentAvatarp->getRotation(); +        } +        else +        { +            target_rot = gAgent.getFrameAgent().getQuaternion(); +        } +        gAgent.startAutoPilotGlobal(posGlobal, "Sit", &target_rot, near_sit_down_point, NULL, 0.7f); +        return true; +    } +}; + +class LLLandCanSit : public view_listener_t +{ +    bool handleEvent(const LLSD& userdata) +    { +        LLVector3d posGlobal = LLToolPie::getInstance()->getPick().mPosGlobal; +        return !posGlobal.isExactlyZero(); // valid position, not beyond draw distance +    }  };  //------------------------------------------------------------------- @@ -4949,7 +5002,7 @@ void handle_buy_or_take()  		{  			LLStringUtil::format_map_t args;  			args["AMOUNT"] = llformat("%d", total_price); -			LLBuyCurrencyHTML::openCurrencyFloater( LLTrans::getString( "BuyingCosts", args ), total_price ); +			LLBuyCurrencyHTML::openCurrencyFloater( LLTrans::getString( "this_object_costs", args ), total_price );  		}  	}  	else @@ -4978,13 +5031,6 @@ bool tools_visible_take_object()  	return !is_selection_buy_not_take();  } -bool enable_how_to_visible(const LLSD& param) -{ -	LLFloaterWebContent::Params p; -	p.target = "__help_how_to"; -	return LLFloaterReg::instanceVisible("how_to", p); -} -  class LLToolsEnableBuyOrTake : public view_listener_t  {  	bool handleEvent(const LLSD& userdata) @@ -5940,6 +5986,16 @@ class LLWorldSetHomeLocation : public view_listener_t  	}  }; +class LLWorldLindenHome : public view_listener_t +{ +	bool handleEvent(const LLSD& userdata) +	{ +		std::string url = LLFloaterLandHoldings::sHasLindenHome ? LLTrans::getString("lindenhomes_my_home_url") : LLTrans::getString("lindenhomes_get_home_url"); +		LLWeb::loadURL(url); +		return true; +	} +}; +  class LLWorldTeleportHome : public view_listener_t  {  	bool handleEvent(const LLSD& userdata) @@ -6022,7 +6078,7 @@ class LLWorldCreateLandmark : public view_listener_t  {  	bool handleEvent(const LLSD& userdata)  	{ -		LLFloaterSidePanelContainer::showPanel("places", LLSD().with("type", "create_landmark")); +		LLFloaterReg::showInstance("add_landmark");  		return true;  	} @@ -6376,6 +6432,11 @@ void handle_edit_outfit()  	LLFloaterSidePanelContainer::showPanel("appearance", LLSD().with("type", "edit_outfit"));  } +void handle_now_wearing() +{ +    LLFloaterSidePanelContainer::showPanel("appearance", LLSD().with("type", "now_wearing")); +} +  void handle_edit_shape()  {  	LLFloaterSidePanelContainer::showPanel("appearance", LLSD().with("type", "edit_shape")); @@ -7741,15 +7802,7 @@ class LLToggleHowTo : public view_listener_t  {  	bool handleEvent(const LLSD& userdata)  	{ -		LLFloaterWebContent::Params p; -		std::string url = gSavedSettings.getString("HowToHelpURL"); -		p.url = LLWeb::expandURLSubstitutions(url, LLSD()); -		p.show_chrome = false; -		p.target = "__help_how_to"; -		p.show_page_title = false; -		p.preferred_media_size = LLRect(0, 460, 335, 0); - -		LLFloaterReg::toggleInstanceOrBringToFront("how_to", p); +		LLFloaterReg::toggleInstanceOrBringToFront("guidebook");  		return true;  	}  }; @@ -8078,6 +8131,16 @@ void force_error_driver_crash(void *)      LLAppViewer::instance()->forceErrorDriverCrash();  } +void force_error_coroutine_crash(void *) +{ +    LLAppViewer::instance()->forceErrorCoroutineCrash(); +} + +void force_error_thread_crash(void *) +{ +    LLAppViewer::instance()->forceErrorThreadCrash(); +} +  class LLToolsUseSelectionForGrid : public view_listener_t  {  	bool handleEvent(const LLSD& userdata) @@ -8619,37 +8682,32 @@ class LLWorldEnvSettings : public view_listener_t  		if (event_name == "sunrise")  		{ -            LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::KNOWN_SKY_SUNRISE); -            LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL); -            LLEnvironment::instance().updateEnvironment(); +            LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::KNOWN_SKY_SUNRISE, LLEnvironment::TRANSITION_INSTANT); +            LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::TRANSITION_INSTANT);              defocusEnvFloaters();  		}  		else if (event_name == "noon")  		{ -            LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::KNOWN_SKY_MIDDAY); -            LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL); -            LLEnvironment::instance().updateEnvironment(); +            LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::KNOWN_SKY_MIDDAY, LLEnvironment::TRANSITION_INSTANT); +            LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::TRANSITION_INSTANT);              defocusEnvFloaters();  		}  		else if (event_name == "sunset")  		{ -            LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::KNOWN_SKY_SUNSET); -            LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL); -            LLEnvironment::instance().updateEnvironment(); +            LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::KNOWN_SKY_SUNSET, LLEnvironment::TRANSITION_INSTANT); +            LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::TRANSITION_INSTANT);              defocusEnvFloaters();  		}  		else if (event_name == "midnight")  		{ -            LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::KNOWN_SKY_MIDNIGHT); -            LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL); -            LLEnvironment::instance().updateEnvironment(); +            LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::KNOWN_SKY_MIDNIGHT, LLEnvironment::TRANSITION_INSTANT); +            LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::TRANSITION_INSTANT);              defocusEnvFloaters();  		}          else if (event_name == "region")  		{              LLEnvironment::instance().clearEnvironment(LLEnvironment::ENV_LOCAL); -            LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL); -            LLEnvironment::instance().updateEnvironment(); +            LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::TRANSITION_INSTANT);              defocusEnvFloaters();  		}          else if (event_name == "pause_clouds") @@ -8820,6 +8878,17 @@ public:  	}  }; +class LLUpdateMembershipLabel : public view_listener_t +{ +	bool handleEvent(const LLSD& userdata) +	{ +		const std::string label_str =  LLAgentBenefitsMgr::isCurrent("Base") ? LLTrans::getString("MembershipUpgradeText") : LLTrans::getString("MembershipPremiumText"); +		gMenuHolder->childSetLabelArg("Membership", "[Membership]", label_str); + +		return true; +	} +}; +  void handle_voice_morphing_subscribe()  {  	LLWeb::loadURL(LLTrans::getString("voice_morphing_url")); @@ -8969,11 +9038,13 @@ void initialize_menus()  	view_listener_t::addEnable(new LLUploadCostCalculator(), "Upload.CalculateCosts"); +	view_listener_t::addEnable(new LLUpdateMembershipLabel(), "Membership.UpdateLabel"); +  	enable.add("Conversation.IsConversationLoggingAllowed", boost::bind(&LLFloaterIMContainer::isConversationLoggingAllowed));  	// Agent  	commit.add("Agent.toggleFlying", boost::bind(&LLAgent::toggleFlying)); -	enable.add("Agent.enableFlying", boost::bind(&LLAgent::enableFlying)); +	enable.add("Agent.enableFlyLand", boost::bind(&enable_fly_land));  	commit.add("Agent.PressMicrophone", boost::bind(&LLAgent::pressMicrophone, _2));  	commit.add("Agent.ReleaseMicrophone", boost::bind(&LLAgent::releaseMicrophone, _2));  	commit.add("Agent.ToggleMicrophone", boost::bind(&LLAgent::toggleMicrophone, _2)); @@ -8989,6 +9060,7 @@ void initialize_menus()  	view_listener_t::addMenu(new LLEnableHoverHeight(), "Edit.EnableHoverHeight");  	view_listener_t::addMenu(new LLEnableEditPhysics(), "Edit.EnableEditPhysics");  	commit.add("CustomizeAvatar", boost::bind(&handle_customize_avatar)); +    commit.add("NowWearing", boost::bind(&handle_now_wearing));  	commit.add("EditOutfit", boost::bind(&handle_edit_outfit));  	commit.add("EditShape", boost::bind(&handle_edit_shape));  	commit.add("HoverHeight", boost::bind(&handle_hover_height)); @@ -9021,9 +9093,6 @@ void initialize_menus()  	view_listener_t::addMenu(new LLViewStatusDoNotDisturb(), "View.Status.CheckDoNotDisturb");  	view_listener_t::addMenu(new LLViewCheckHUDAttachments(), "View.CheckHUDAttachments"); -	// Me > Movement -	view_listener_t::addMenu(new LLAdvancedAgentFlyingInfo(), "Agent.getFlying"); -  	//Communicate Nearby chat  	view_listener_t::addMenu(new LLCommunicateNearbyChat(), "Communicate.NearbyChat"); @@ -9045,6 +9114,7 @@ void initialize_menus()  	view_listener_t::addMenu(new LLWorldTeleportHome(), "World.TeleportHome");  	view_listener_t::addMenu(new LLWorldSetAway(), "World.SetAway");  	view_listener_t::addMenu(new LLWorldSetDoNotDisturb(), "World.SetDoNotDisturb"); +	view_listener_t::addMenu(new LLWorldLindenHome(), "World.LindenHome");  	view_listener_t::addMenu(new LLWorldEnableCreateLandmark(), "World.EnableCreateLandmark");  	view_listener_t::addMenu(new LLWorldEnableSetHomeLocation(), "World.EnableSetHomeLocation"); @@ -9099,7 +9169,6 @@ void initialize_menus()  	// Help menu  	// most items use the ShowFloater method  	view_listener_t::addMenu(new LLToggleHowTo(), "Help.ToggleHowTo"); -	enable.add("Help.HowToVisible", boost::bind(&enable_how_to_visible, _2));  	// Advanced menu  	view_listener_t::addMenu(new LLAdvancedToggleConsole(), "Advanced.ToggleConsole"); @@ -9244,6 +9313,8 @@ void initialize_menus()  	view_listener_t::addMenu(new LLAdvancedForceErrorInfiniteLoop(), "Advanced.ForceErrorInfiniteLoop");  	view_listener_t::addMenu(new LLAdvancedForceErrorSoftwareException(), "Advanced.ForceErrorSoftwareException");  	view_listener_t::addMenu(new LLAdvancedForceErrorDriverCrash(), "Advanced.ForceErrorDriverCrash"); +    view_listener_t::addMenu(new LLAdvancedForceErrorCoroutineCrash(), "Advanced.ForceErrorCoroutineCrash"); +    view_listener_t::addMenu(new LLAdvancedForceErrorThreadCrash(), "Advanced.ForceErrorThreadCrash");  	view_listener_t::addMenu(new LLAdvancedForceErrorDisconnectViewer(), "Advanced.ForceErrorDisconnectViewer");  	// Advanced (toplevel) @@ -9287,11 +9358,8 @@ void initialize_menus()  	view_listener_t::addMenu(new LLAdminOnSaveState(), "Admin.OnSaveState");  	// Self context menu -	view_listener_t::addMenu(new LLSelfStandUp(), "Self.StandUp"); -	enable.add("Self.EnableStandUp", boost::bind(&enable_standup_self)); -	view_listener_t::addMenu(new LLSelfSitDown(), "Self.SitDown"); -	enable.add("Self.EnableSitDown", boost::bind(&enable_sitdown_self));  -	enable.add("Self.ShowSitDown", boost::bind(&show_sitdown_self)); +	view_listener_t::addMenu(new LLSelfToggleSitStand(), "Self.ToggleSitStand"); +	enable.add("Self.EnableSitStand", boost::bind(&enable_sit_stand));  	view_listener_t::addMenu(new LLSelfRemoveAllAttachments(), "Self.RemoveAllAttachments");  	view_listener_t::addMenu(new LLSelfEnableRemoveAllAttachments(), "Self.EnableRemoveAllAttachments"); @@ -9380,6 +9448,7 @@ void initialize_menus()  	// Land pie menu  	view_listener_t::addMenu(new LLLandBuild(), "Land.Build");  	view_listener_t::addMenu(new LLLandSit(), "Land.Sit"); +    view_listener_t::addMenu(new LLLandCanSit(), "Land.CanSit");  	view_listener_t::addMenu(new LLLandBuyPass(), "Land.BuyPass");  	view_listener_t::addMenu(new LLLandEdit(), "Land.Edit"); diff --git a/indra/newview/llviewermenu.h b/indra/newview/llviewermenu.h index 0f63c8cf58..36b6971c81 100644 --- a/indra/newview/llviewermenu.h +++ b/indra/newview/llviewermenu.h @@ -188,10 +188,14 @@ extern LLContextMenu		*gMenuMuteParticle;  extern LLMenuGL* gAttachSubMenu;  extern LLMenuGL* gDetachSubMenu;  extern LLMenuGL* gTakeOffClothes; +extern LLMenuGL* gDetachAvatarMenu; +extern LLMenuGL* gDetachHUDAvatarMenu;  extern LLContextMenu* gAttachScreenPieMenu;  extern LLContextMenu* gDetachScreenPieMenu; +extern LLContextMenu* gDetachHUDAttSelfMenu;  extern LLContextMenu* gAttachPieMenu;  extern LLContextMenu* gDetachPieMenu; +extern LLContextMenu* gDetachAttSelfMenu;  extern LLContextMenu* gAttachBodyPartPieMenus[9];  extern LLContextMenu* gDetachBodyPartPieMenus[9]; diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp index 4b231c7067..15181dcd9f 100644 --- a/indra/newview/llviewermenufile.cpp +++ b/indra/newview/llviewermenufile.cpp @@ -830,10 +830,7 @@ void upload_done_callback(  				if(!(can_afford_transaction(expected_upload_cost)))  				{ -					LLStringUtil::format_map_t args; -					args["NAME"] = data->mAssetInfo.getName(); -					args["AMOUNT"] = llformat("%d", expected_upload_cost); -					LLBuyCurrencyHTML::openCurrencyFloater( LLTrans::getString("UploadingCosts", args), expected_upload_cost ); +					LLBuyCurrencyHTML::openCurrencyFloater( "", expected_upload_cost );  					is_balance_sufficient = FALSE;  				}  				else if(region) @@ -967,10 +964,7 @@ void upload_new_resource(  			if (balance < uploadInfo->getExpectedUploadCost())  			{  				// insufficient funds, bail on this upload -				LLStringUtil::format_map_t args; -				args["NAME"] = uploadInfo->getName(); -                args["AMOUNT"] = llformat("%d", uploadInfo->getExpectedUploadCost()); -                LLBuyCurrencyHTML::openCurrencyFloater(LLTrans::getString("UploadingCosts", args), uploadInfo->getExpectedUploadCost()); +                LLBuyCurrencyHTML::openCurrencyFloater("", uploadInfo->getExpectedUploadCost());  				return;  			}  		} diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 458fc3b13d..39c891c9c1 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -116,7 +116,6 @@  #include "llviewerregion.h"  #include "llfloaterregionrestarting.h" -#include <boost/algorithm/string/split.hpp> //  #include <boost/foreach.hpp>  #include "llnotificationmanager.h" // @@ -778,7 +777,6 @@ void response_group_invitation_coro(std::string url, LLUUID group_id, bool notif              LL_DEBUGS("GroupInvite") << "Successfully sent response to group " << group_id << " invitation" << LL_ENDL;              if (notify_and_update)              { -                LLNotificationsUtil::add("JoinGroupSuccess");                  gAgent.sendAgentDataUpdateRequest();                  LLGroupMgr::getInstance()->clearGroupData(group_id); @@ -5058,6 +5056,15 @@ bool attempt_standard_notification(LLMessageSystem* msgsystem)  		// notification was specified using the new mechanism, so we can just handle it here  		std::string notificationID;  		msgsystem->getStringFast(_PREHASH_AlertInfo, _PREHASH_Message, notificationID); + +		//SL-13824 skip notification when both joining a group and leaving a group +		//remove this after server stops sending these messages   +		if (notificationID == "JoinGroupSuccess" || +			notificationID == "GroupDepart") +		{ +			return true; +		} +  		if (!LLNotifications::getInstance()->templateExists(notificationID))  		{  			return false; diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp index d5365e4ee8..06172e366d 100644 --- a/indra/newview/llviewerparcelmgr.cpp +++ b/indra/newview/llviewerparcelmgr.cpp @@ -1715,9 +1715,6 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use  			// Let interesting parties know about agent parcel change.  			LLViewerParcelMgr* instance = LLViewerParcelMgr::getInstance(); -			// Notify anything that wants to know when the agent changes parcels -			gAgent.changeParcels(); -  			if (instance->mTeleportInProgress)  			{  				instance->mTeleportInProgress = FALSE; @@ -1733,6 +1730,7 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use  			}              parcel->setParcelEnvironmentVersion(parcel_environment_version);              LL_DEBUGS("ENVIRONMENT") << "Parcel environment version is " << parcel->getParcelEnvironmentVersion() << LL_ENDL; +              // Notify anything that wants to know when the agent changes parcels              gAgent.changeParcels();              instance->mTeleportInProgress = FALSE; diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 2fde4fe49c..7628a6c7ef 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -82,6 +82,8 @@  #include "llcallstack.h"  #include "llsettingsdaycycle.h" +#include <boost/regex.hpp> +  #ifdef LL_WINDOWS  	#pragma warning(disable:4355)  #endif @@ -143,15 +145,22 @@ public:          // build a secondlife://{PLACE} SLurl from this SLapp          std::string url = "secondlife://"; +		boost::regex name_rx("[A-Za-z0-9()_%]+"); +		boost::regex coord_rx("[0-9]+");          for (int i = 0; i < num_params; i++)          {              if (i > 0)              {                  url += "/";              } +			if (!boost::regex_match(params[i].asString(), i > 0 ? coord_rx : name_rx)) +			{ +				return false; +			} +              url += params[i].asString();          } -            +          // Process the SLapp as if it was a secondlife://{PLACE} SLurl          LLURLDispatcher::dispatch(url, "clicked", web, true);          return true; @@ -2241,7 +2250,7 @@ void LLViewerRegion::setSimulatorFeaturesReceived(bool received)  	mSimulatorFeaturesReceived = received;  	if (received)  	{ -		mSimulatorFeaturesReceivedSignal(getRegionID()); +		mSimulatorFeaturesReceivedSignal(getRegionID(), this);  		mSimulatorFeaturesReceivedSignal.disconnect_all_slots();  	}  } @@ -3183,7 +3192,7 @@ void LLViewerRegion::setCapabilitiesReceived(bool received)  	// so that they can safely use getCapability().  	if (received)  	{ -		mCapabilitiesReceivedSignal(getRegionID()); +		mCapabilitiesReceivedSignal(getRegionID(), this);  		LLFloaterPermsDefault::sendInitialPerms(); diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h index dfd8c64f76..fcbf56c81f 100644 --- a/indra/newview/llviewerregion.h +++ b/indra/newview/llviewerregion.h @@ -94,7 +94,7 @@ public:  		NUM_PARTITIONS  	} eObjectPartitions; -	typedef boost::signals2::signal<void(const LLUUID& region_id)> caps_received_signal_t; +	typedef boost::signals2::signal<void(const LLUUID& region_id, LLViewerRegion* regionp)> caps_received_signal_t;  	LLViewerRegion(const U64 &handle,  				   const LLHost &host, diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp index 05f88b0a75..314c1a1f1e 100644 --- a/indra/newview/llviewerstats.cpp +++ b/indra/newview/llviewerstats.cpp @@ -63,6 +63,7 @@  #include "llsdutil.h"  #include "llcorehttputil.h"  #include "llvoicevivox.h" +#include "lluiusage.h"  namespace LLStatViewer  { @@ -577,6 +578,8 @@ void send_viewer_stats(bool include_preferences)  	fail["invalid"] = (S32) gMessageSystem->mInvalidOnCircuitPackets;  	fail["missing_updater"] = (S32) LLAppViewer::instance()->isUpdaterMissing(); +	body["ui"] = LLUIUsage::instance().asLLSD(); +		  	body["stats"]["voice"] = LLVoiceVivoxStats::getInstance()->read();  	// Misc stats, two strings and two ints diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 21985d5a8a..1d13a306ef 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -1928,7 +1928,8 @@ LLViewerWindow::LLViewerWindow(const Params& p)  	if (!LLAppViewer::instance()->restoreErrorTrap())  	{ -		LL_WARNS("Window") << " Someone took over my signal/exception handler (post createWindow)!" << LL_ENDL; +        // this always happens, so downgrading it to INFO +		LL_INFOS("Window") << " Someone took over my signal/exception handler (post createWindow; normal)" << LL_ENDL;  	}  	const bool do_not_enforce = false; @@ -2700,7 +2701,7 @@ void LLViewerWindow::draw()  	if (!gSavedSettings.getBOOL("RenderUIBuffer"))  	{ -		LLUI::getInstance()->mDirtyRect = getWindowRectScaled(); +		LLView::sDirtyRect = getWindowRectScaled();  	}  	// HACK for timecode debugging diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index f69b9b3861..e085a945a8 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -10584,7 +10584,8 @@ void LLVOAvatar::accountRenderComplexityForObject(                              LL_DEBUGS("ARCdetail") << "Attachment costs " << attached_object->getAttachmentItemID()                                                     << " total: " << attachment_total_cost                                                     << ", volume: " << attachment_volume_cost -                                                   << ", textures: " << attachment_texture_cost +                                                   << ", " << textures.size() +                                                   << " textures: " << attachment_texture_cost                                                     << ", " << volume->numChildren()                                                     << " children: " << attachment_children_cost                                                     << LL_ENDL; @@ -10684,10 +10685,23 @@ void LLVOAvatar::calculateUpdateRenderComplexity()  			ETextureIndex tex_index = baked_dict->mTextureIndex;  			if ((tex_index != TEX_SKIRT_BAKED) || (isWearingWearableType(LLWearableType::WT_SKIRT)))  			{ -				if (isTextureVisible(tex_index)) -				{ -					cost +=COMPLEXITY_BODY_PART_COST; -				} +                // Same as isTextureVisible(), but doesn't account for isSelf to ensure identical numbers for all avatars +                if (isIndexLocalTexture(tex_index)) +                { +                    if (isTextureDefined(tex_index, 0)) +                    { +                        cost += COMPLEXITY_BODY_PART_COST; +                    } +                } +                else +                { +                    // baked textures can use TE images directly +                    if (isTextureDefined(tex_index) +                        && (getTEImage(tex_index)->getID() != IMG_INVISIBLE || LLDrawPoolAlpha::sShowDebugAlpha)) +                    { +                        cost += COMPLEXITY_BODY_PART_COST; +                    } +                }  			}  		}          LL_DEBUGS("ARCdetail") << "Avatar body parts complexity: " << cost << LL_ENDL; @@ -10728,8 +10742,7 @@ void LLVOAvatar::calculateUpdateRenderComplexity()  		// Diagnostic output to identify all avatar-related textures.  		// Does not affect rendering cost calculation. -		// Could be wrapped in a debug option if output becomes problematic. -		if (isSelf()) +		if (isSelf() && debugLoggingEnabled("ARCdetail"))  		{  			// print any attachment textures we didn't already know about.  			for (LLVOVolume::texture_cost_t::iterator it = textures.begin(); it != textures.end(); ++it) diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index 458d8ced65..7faca2ee5b 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -465,6 +465,8 @@ BOOL LLVOAvatarSelf::buildMenus()  		if (gDetachBodyPartPieMenus[i])  		{  			gDetachPieMenu->appendContextSubMenu( gDetachBodyPartPieMenus[i] ); +			gDetachAttSelfMenu->appendContextSubMenu(gDetachBodyPartPieMenus[i]); +			gDetachAvatarMenu->appendContextSubMenu(gDetachBodyPartPieMenus[i]);  		}  		else  		{ @@ -493,12 +495,14 @@ BOOL LLVOAvatarSelf::buildMenus()  					LLMenuItemCallGL* item = LLUICtrlFactory::create<LLMenuItemCallGL>(item_params);  					gDetachPieMenu->addChild(item); -						 +					gDetachAttSelfMenu->addChild(LLUICtrlFactory::create<LLMenuItemCallGL>(item_params)); +					gDetachAvatarMenu->addChild(LLUICtrlFactory::create<LLMenuItemCallGL>(item_params));  					break;  				}  			}  		}  	} +	  	// add screen attachments  	for (attachment_map_t::iterator iter = mAttachmentPoints.begin();  @@ -532,6 +536,8 @@ BOOL LLVOAvatarSelf::buildMenus()  			item_params.on_enable.parameter = iter->first;  			item = LLUICtrlFactory::create<LLMenuItemCallGL>(item_params);  			gDetachScreenPieMenu->addChild(item); +			gDetachHUDAttSelfMenu->addChild(LLUICtrlFactory::create<LLMenuItemCallGL>(item_params)); +			gDetachHUDAvatarMenu->addChild(LLUICtrlFactory::create<LLMenuItemCallGL>(item_params));  		}  	} diff --git a/indra/newview/llvocache.cpp b/indra/newview/llvocache.cpp index 689eeee0e3..5ebc65405f 100644 --- a/indra/newview/llvocache.cpp +++ b/indra/newview/llvocache.cpp @@ -44,6 +44,9 @@ F32 LLVOCacheEntry::sFrontPixelThreshold = 1.0f;  F32 LLVOCacheEntry::sRearPixelThreshold = 1.0f;  BOOL LLVOCachePartition::sNeedsOcclusionCheck = FALSE; +const S32 ENTRY_HEADER_SIZE = 6 * sizeof(S32); +const S32 MAX_ENTRY_BODY_SIZE = 10000; +  BOOL check_read(LLAPRFile* apr_file, void* src, S32 n_bytes)   {  	return apr_file->read(src, n_bytes) == n_bytes ; @@ -111,32 +114,22 @@ LLVOCacheEntry::LLVOCacheEntry(LLAPRFile* apr_file)  {  	S32 size = -1;  	BOOL success; +    static U8 data_buffer[ENTRY_HEADER_SIZE];  	mDP.assignBuffer(mBuffer, 0); -	 -	success = check_read(apr_file, &mLocalID, sizeof(U32)); -	if(success) -	{ -		success = check_read(apr_file, &mCRC, sizeof(U32)); -	} -	if(success) -	{ -		success = check_read(apr_file, &mHitCount, sizeof(S32)); -	} -	if(success) -	{ -		success = check_read(apr_file, &mDupeCount, sizeof(S32)); -	} -	if(success) -	{ -		success = check_read(apr_file, &mCRCChangeCount, sizeof(S32)); -	} -	if(success) -	{ -		success = check_read(apr_file, &size, sizeof(S32)); + +    success = check_read(apr_file, (void *)data_buffer, ENTRY_HEADER_SIZE); +    if (success) +    { +        memcpy(&mLocalID, data_buffer, sizeof(U32)); +        memcpy(&mCRC, data_buffer + sizeof(U32), sizeof(U32)); +        memcpy(&mHitCount, data_buffer + (2 * sizeof(U32)), sizeof(S32)); +        memcpy(&mDupeCount, data_buffer + (3 * sizeof(U32)), sizeof(S32)); +        memcpy(&mCRCChangeCount, data_buffer + (4 * sizeof(U32)), sizeof(S32)); +        memcpy(&size, data_buffer + (5 * sizeof(U32)), sizeof(S32));  		// Corruption in the cache entries -		if ((size > 10000) || (size < 1)) +		if ((size > MAX_ENTRY_BODY_SIZE) || (size < 1))  		{  			// We've got a bogus size, skip reading it.  			// We won't bother seeking, because the rest of this file @@ -345,26 +338,25 @@ void LLVOCacheEntry::dump() const  		<< LL_ENDL;  } -BOOL LLVOCacheEntry::writeToFile(LLAPRFile* apr_file) const +S32 LLVOCacheEntry::writeToBuffer(U8 *data_buffer) const  { -    static const S32 data_buffer_size = 6 * sizeof(S32); -    static U8 data_buffer[data_buffer_size];      S32 size = mDP.getBufferSize(); +    if (size > MAX_ENTRY_BODY_SIZE) +    { +        LL_WARNS() << "Failed to write entry with size above allowed limit: " << size << LL_ENDL; +        return 0; +    } +      memcpy(data_buffer, &mLocalID, sizeof(U32));      memcpy(data_buffer + sizeof(U32), &mCRC, sizeof(U32));      memcpy(data_buffer + (2 * sizeof(U32)), &mHitCount, sizeof(S32));      memcpy(data_buffer + (3 * sizeof(U32)), &mDupeCount, sizeof(S32));      memcpy(data_buffer + (4 * sizeof(U32)), &mCRCChangeCount, sizeof(S32));      memcpy(data_buffer + (5 * sizeof(U32)), &size, sizeof(S32)); +    memcpy(data_buffer + ENTRY_HEADER_SIZE, (void*)mBuffer, size); -    BOOL success = check_write(apr_file, (void*)data_buffer, data_buffer_size); -    if (success) -    { -        success = check_write(apr_file, (void*)mBuffer, size); -    } - -    return success; +    return ENTRY_HEADER_SIZE + size;  }  //static  @@ -1393,11 +1385,11 @@ void LLVOCache::readFromCache(U64 handle, const LLUUID& id, LLVOCacheEntry::voca  	bool success = true ;  	{  		std::string filename; +		LLUUID cache_id;  		getObjectCacheFilename(handle, filename);  		LLAPRFile apr_file(filename, APR_READ|APR_BINARY, mLocalAPRFilePoolp); -		LLUUID cache_id ; -		success = check_read(&apr_file, cache_id.mData, UUID_BYTES) ; +		success = check_read(&apr_file, cache_id.mData, UUID_BYTES);  		if(success)  		{		 @@ -1409,7 +1401,7 @@ void LLVOCache::readFromCache(U64 handle, const LLUUID& id, LLVOCacheEntry::voca  			if(success)  			{ -				S32 num_entries; +				S32 num_entries;  // if removal was enabled during write num_entries might be wrong  				success = check_read(&apr_file, &num_entries, sizeof(S32)) ;  				if(success) @@ -1516,28 +1508,57 @@ void LLVOCache::writeToCache(U64 handle, const LLUUID& id, const LLVOCacheEntry:  	{  		std::string filename;  		getObjectCacheFilename(handle, filename); -		LLAPRFile apr_file(filename, APR_CREATE|APR_WRITE|APR_BINARY, mLocalAPRFilePoolp); +		LLAPRFile apr_file(filename, APR_CREATE|APR_WRITE|APR_BINARY|APR_TRUNCATE, mLocalAPRFilePoolp); -		success = check_write(&apr_file, (void*)id.mData, UUID_BYTES) ; - +		success = check_write(&apr_file, (void*)id.mData, UUID_BYTES);  		if(success)  		{ -			S32 num_entries = cache_entry_map.size() ; +			S32 num_entries = cache_entry_map.size(); // if removal is enabled num_entries might be wrong  			success = check_write(&apr_file, &num_entries, sizeof(S32)); - -			// This can have a lot of entries, so might be better to dump them into buffer first and write in one go. -			for (LLVOCacheEntry::vocache_entry_map_t::const_iterator iter = cache_entry_map.begin(); success && iter != cache_entry_map.end(); ++iter) -			{ -				if(!removal_enabled || iter->second->isValid()) -				{ -					success = iter->second->writeToFile(&apr_file) ; -					if(!success) -					{ -						break; -					} -				} -			} +            if (success) +            { +                const S32 buffer_size = 32768; //should be large enough for couple MAX_ENTRY_BODY_SIZE +                U8 data_buffer[buffer_size]; // generaly entries are fairly small, so collect them and drop onto disk in one go +                S32 size_in_buffer = 0; + +                // This can have a lot of entries, so might be better to dump them into buffer first and write in one go. +                for (LLVOCacheEntry::vocache_entry_map_t::const_iterator iter = cache_entry_map.begin(); success && iter != cache_entry_map.end(); ++iter) +                { +                    if (!removal_enabled || iter->second->isValid()) +                    { +                        S32 size = iter->second->writeToBuffer(data_buffer + size_in_buffer); + +                        if (size > ENTRY_HEADER_SIZE) // body is minimum of 1 +                        { +                            size_in_buffer += size; +                        } +                        else +                        { +                            success = false; +                            break; +                        } + +                        // Make sure we have space in buffer for next element +                        if (buffer_size - size_in_buffer < MAX_ENTRY_BODY_SIZE + ENTRY_HEADER_SIZE) +                        { +                            success = check_write(&apr_file, (void*)data_buffer, size_in_buffer); +                            size_in_buffer = 0; +                            if (!success) +                            { +                                break; +                            } +                        } +                    } +                } + +                if (success && size_in_buffer > 0) +                { +                    // final write +                    success = check_write(&apr_file, (void*)data_buffer, size_in_buffer); +                    size_in_buffer = 0; +                } +            }  		}  	} diff --git a/indra/newview/llvocache.h b/indra/newview/llvocache.h index 6c95541c11..dd6afd6b85 100644 --- a/indra/newview/llvocache.h +++ b/indra/newview/llvocache.h @@ -106,7 +106,7 @@ public:  	F32 getSceneContribution() const             { return mSceneContrib;}  	void dump() const; -	BOOL writeToFile(LLAPRFile* apr_file) const; +	S32 writeToBuffer(U8 *data_buffer) const;  	LLDataPackerBinaryBuffer *getDP();  	void recordHit();  	void recordDupe() { mDupeCount++; } diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index b0f57beff8..4d2eac8c09 100644 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -652,7 +652,6 @@ void LLVivoxVoiceClient::idle(void* user_data)  {  } -  //=========================================================================  // the following are methods to support the coroutine implementation of the   // voice connection and processing.  They should only be called in the context  @@ -684,12 +683,30 @@ void LLVivoxVoiceClient::voiceControlCoro()          bool success = startAndConnectSession();          if (success)          { -            if (mTuningMode) +			// enable/disable the automatic VAD and explicitly set the initial values of  +			// the VAD variables ourselves when it is off - see SL-15072 for more details +			// note: we set the other parameters too even if the auto VAD is on which is ok +			unsigned int vad_auto = gSavedSettings.getU32("VivoxVadAuto"); +			unsigned int vad_hangover = gSavedSettings.getU32("VivoxVadHangover"); +			unsigned int vad_noise_floor = gSavedSettings.getU32("VivoxVadNoiseFloor"); +			unsigned int vad_sensitivity = gSavedSettings.getU32("VivoxVadSensitivity"); +			setupVADParams(vad_auto, vad_hangover, vad_noise_floor, vad_sensitivity); +			 +			// watch for changes to the VAD settings via Debug Settings UI and act on them accordingly +			gSavedSettings.getControl("VivoxVadAuto")->getSignal()->connect(boost::bind(&LLVivoxVoiceClient::onVADSettingsChange, this)); +			gSavedSettings.getControl("VivoxVadHangover")->getSignal()->connect(boost::bind(&LLVivoxVoiceClient::onVADSettingsChange, this)); +			gSavedSettings.getControl("VivoxVadNoiseFloor")->getSignal()->connect(boost::bind(&LLVivoxVoiceClient::onVADSettingsChange, this)); +			gSavedSettings.getControl("VivoxVadSensitivity")->getSignal()->connect(boost::bind(&LLVivoxVoiceClient::onVADSettingsChange, this)); + +			if (mTuningMode && !sShuttingDown)              {                  performMicTuning();              } -            waitForChannel(); // this doesn't normally return unless relog is needed or shutting down +            if (!sShuttingDown) +            { +                waitForChannel(); // this doesn't normally return unless relog is needed or shutting down +            }              LL_DEBUGS("Voice") << "lost channel RelogRequested=" << mRelogRequested << LL_ENDL;                          endAndDisconnectSession(); @@ -731,7 +748,6 @@ void LLVivoxVoiceClient::voiceControlCoro()      LL_INFOS("Voice") << "exiting" << LL_ENDL;  } -  bool LLVivoxVoiceClient::startAndConnectSession()  {      bool ok = false; @@ -1032,7 +1048,14 @@ bool LLVivoxVoiceClient::provisionVoiceAccount()          {              F32 timeout = pow(PROVISION_RETRY_TIMEOUT, static_cast<float>(retryCount));              LL_WARNS("Voice") << "Provision CAP 404.  Retrying in " << timeout << " seconds." << LL_ENDL; -            llcoro::suspendUntilTimeout(timeout); +            if (sShuttingDown) +            { +                return false; +            } +            else +            { +                llcoro::suspendUntilTimeout(timeout); +            }          }          else if (!status)          { @@ -1259,8 +1282,13 @@ bool LLVivoxVoiceClient::loginToVivox()                  // tell the user there is a problem                  LL_WARNS("Voice") << "login " << loginresp << " will retry login in " << timeout << " seconds." << LL_ENDL; -                     -                llcoro::suspendUntilTimeout(timeout); +                 +                if (!sShuttingDown) +                { +                    // Todo: this is way to long, viewer can get stuck waiting during shutdown +                    // either make it listen to pump or split in smaller waits with checks for shutdown +                    llcoro::suspendUntilTimeout(timeout); +                }              }              else if (loginresp == "failed")              { @@ -1326,6 +1354,11 @@ void LLVivoxVoiceClient::logoutOfVivox(bool wait)                  result = llcoro::suspendUntilEventOnWithTimeout(mVivoxPump, LOGOUT_ATTEMPT_TIMEOUT, timeoutResult); +                if (sShuttingDown) +                { +                    break; +                } +                  LL_DEBUGS("Voice") << "event=" << ll_stream_notation_sd(result) << LL_ENDL;                  // Don't get confused by prior queued events -- note that it's                  // very important that mVivoxPump is an LLEventMailDrop, which @@ -1565,6 +1598,12 @@ bool LLVivoxVoiceClient::addAndJoinSession(const sessionStatePtr_t &nextSession)      {          result = llcoro::suspendUntilEventOnWithTimeout(mVivoxPump, SESSION_JOIN_TIMEOUT, timeoutResult); +        if (sShuttingDown) +        { +            mIsJoiningSession = false; +            return false; +        } +          LL_INFOS("Voice") << "event=" << ll_stream_notation_sd(result) << LL_ENDL;          if (result.has("session"))          { @@ -1759,7 +1798,7 @@ bool LLVivoxVoiceClient::waitForChannel()          if (sShuttingDown)          { -            logoutOfVivox(true); +            logoutOfVivox(false);              return false;          } @@ -1803,7 +1842,7 @@ bool LLVivoxVoiceClient::waitForChannel()                  // the parcel is changed, or we have no pending audio sessions,                  // so try to request the parcel voice info                  // if we have the cap, we move to the appropriate state -                requestParcelVoiceInfo(); +                requestParcelVoiceInfo(); //suspends for http reply              }              else if (sessionNeedsRelog(mNextAudioSession))              { @@ -1815,7 +1854,7 @@ bool LLVivoxVoiceClient::waitForChannel()              {                  sessionStatePtr_t joinSession = mNextAudioSession;                  mNextAudioSession.reset(); -                if (!runSession(joinSession)) +                if (!runSession(joinSession)) //suspends                  {                      LL_DEBUGS("Voice") << "runSession returned false; leaving inner loop" << LL_ENDL;                      break; @@ -1830,7 +1869,7 @@ bool LLVivoxVoiceClient::waitForChannel()                  }              } -            if (!mNextAudioSession) +            if (!mNextAudioSession && !sShuttingDown)              {                  llcoro::suspendUntilTimeout(1.0);              } @@ -1851,9 +1890,9 @@ bool LLVivoxVoiceClient::waitForChannel()          mIsProcessingChannels = false; -        logoutOfVivox(true); +        logoutOfVivox(!sShuttingDown /*bool wait*/); -        if (mRelogRequested) +        if (mRelogRequested && !sShuttingDown)          {              LL_DEBUGS("Voice") << "Relog Requested, restarting provisioning" << LL_ENDL;              if (!provisionVoiceAccount()) @@ -1903,7 +1942,12 @@ bool LLVivoxVoiceClient::runSession(const sessionStatePtr_t &session)      while (mVoiceEnabled && isGatewayRunning() && !mSessionTerminateRequested && !mTuningMode)      { -        sendCaptureAndRenderDevices(); +        sendCaptureAndRenderDevices(); // suspends +        if (mSessionTerminateRequested) +        { +            break; +        } +          if (mAudioSession && mAudioSession->mParticipantsChanged)          {              mAudioSession->mParticipantsChanged = false; @@ -2130,7 +2174,7 @@ bool LLVivoxVoiceClient::performMicTuning()      mIsInTuningMode = true;      llcoro::suspend(); -    while (mTuningMode) +    while (mTuningMode && !sShuttingDown)      {          if (mCaptureDeviceDirty || mRenderDeviceDirty) @@ -2166,9 +2210,12 @@ bool LLVivoxVoiceClient::performMicTuning()          tuningCaptureStartSendMessage(1);  // 1-loop, zero, don't loop          //--------------------------------------------------------------------- -        llcoro::suspend(); +        if (!sShuttingDown) +        { +            llcoro::suspend(); +        } -        while (mTuningMode && !mCaptureDeviceDirty && !mRenderDeviceDirty) +        while (mTuningMode && !mCaptureDeviceDirty && !mRenderDeviceDirty && !sShuttingDown)          {              // process mic/speaker volume changes              if (mTuningMicVolumeDirty || mTuningSpeakerVolumeDirty) @@ -2208,7 +2255,7 @@ bool LLVivoxVoiceClient::performMicTuning()          // transition out of mic tuning          tuningCaptureStopSendMessage(); -        if (mCaptureDeviceDirty || mRenderDeviceDirty) +        if ((mCaptureDeviceDirty || mRenderDeviceDirty) && !sShuttingDown)          {              llcoro::suspendUntilTimeout(UPDATE_THROTTLE_SECONDS);          } @@ -3230,6 +3277,73 @@ void LLVivoxVoiceClient::sendLocalAudioUpdates()  	}  } +/** + * Because of the recurring voice cutout issues (SL-15072) we are going to try + * to disable the automatic VAD (Voice Activity Detection) and set the associated + * parameters directly. We will expose them via Debug Settings and that should + * let us iterate on a collection of values that work for us. Hopefully!  + * + * From the VIVOX Docs: + * + * VadAuto: A flag indicating if the automatic VAD is enabled (1) or disabled (0) + * + * VadHangover: The time (in milliseconds) that it takes + * for the VAD to switch back to silence from speech mode after the last speech + * frame has been detected. + * + * VadNoiseFloor: A dimensionless value between 0 and  + * 20000 (default 576) that controls the maximum level at which the noise floor + * may be set at by the VAD's noise tracking. Too low of a value will make noise + * tracking ineffective (A value of 0 disables noise tracking and the VAD then  + * relies purely on the sensitivity property). Too high of a value will make  + * long speech classifiable as noise. + * + * VadSensitivity: A dimensionless value between 0 and  + * 100, indicating the 'sensitivity of the VAD'. Increasing this value corresponds + * to decreasing the sensitivity of the VAD (i.e. '0' is most sensitive,  + * while 100 is 'least sensitive') + */ +void LLVivoxVoiceClient::setupVADParams(unsigned int vad_auto, +                                        unsigned int vad_hangover, +                                        unsigned int vad_noise_floor, +                                        unsigned int vad_sensitivity) +{ +    std::ostringstream stream; + +    LL_INFOS("Voice") << "Setting the automatic VAD to " +        << (vad_auto ? "True" : "False") +		<< " and discrete values to" +		<< " VadHangover = " << vad_hangover +		<< ", VadSensitivity = " << vad_sensitivity +		<< ", VadNoiseFloor = " << vad_noise_floor +        << LL_ENDL; + +	// Create a request to set the VAD parameters: +	stream << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Aux.SetVadProperties.1\">" +               << "<VadAuto>" << vad_auto << "</VadAuto>" +               << "<VadHangover>" << vad_hangover << "</VadHangover>" +               << "<VadSensitivity>" << vad_sensitivity << "</VadSensitivity>" +               << "<VadNoiseFloor>" << vad_noise_floor << "</VadNoiseFloor>" +           << "</Request>\n\n\n"; + +    if (!stream.str().empty()) +    { +        writeString(stream.str()); +    } +} + +void LLVivoxVoiceClient::onVADSettingsChange() +{ +	// pick up the VAD variables (one of which was changed) +	unsigned int vad_auto = gSavedSettings.getU32("VivoxVadAuto"); +	unsigned int vad_hangover = gSavedSettings.getU32("VivoxVadHangover"); +	unsigned int vad_noise_floor = gSavedSettings.getU32("VivoxVadNoiseFloor"); +	unsigned int vad_sensitivity = gSavedSettings.getU32("VivoxVadSensitivity"); + +	// build a VAD params change request and send it to SLVoice +	setupVADParams(vad_auto, vad_hangover, vad_noise_floor, vad_sensitivity); +} +  /////////////////////////////  // Response/Event handlers @@ -7582,6 +7696,18 @@ void LLVivoxProtocolParser::processResponse(std::string tag)  		{  			LLVivoxVoiceClient::getInstance()->accountGetTemplateFontsResponse(statusCode, statusString);  		} +		else if (!stricmp(actionCstr, "Aux.SetVadProperties.1")) +		{ +			// both values of statusCode (old and more recent) indicate valid requests +			if (statusCode != 0 && statusCode != 200) +			{ +				LL_WARNS("Voice") << "Aux.SetVadProperties.1 request failed: " +					<< "statusCode: " << statusCode +					<< " and " +					<< "statusString: " << statusString +					<< LL_ENDL; +			} +		}  		/*  		 else if (!stricmp(actionCstr, "Account.ChannelGetList.1"))  		 { diff --git a/indra/newview/llvoicevivox.h b/indra/newview/llvoicevivox.h index 699c85066b..75ff5429f3 100644 --- a/indra/newview/llvoicevivox.h +++ b/indra/newview/llvoicevivox.h @@ -446,7 +446,6 @@ protected:  	// local audio updates, mic mute, speaker mute, mic volume and speaker volumes  	void sendLocalAudioUpdates(); -  	/////////////////////////////  	// Response/Event handlers  	void connectorCreateResponse(int statusCode, std::string &statusString, std::string &connectorHandle, std::string &versionID); @@ -473,6 +472,12 @@ protected:  	void muteListChanged();  	///////////////////////////// +	// VAD changes +	// disable auto-VAD and configure VAD parameters explicitly +	void setupVADParams(unsigned int vad_auto, unsigned int vad_hangover, unsigned int vad_noise_floor, unsigned int vad_sensitivity); +	void onVADSettingsChange(); + +	/////////////////////////////  	// Sending updates of current state  	void updatePosition(void);  	void setCameraPosition(const LLVector3d &position, const LLVector3 &velocity, const LLMatrix3 &rot); diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 3bdb8a2981..f063800587 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -3987,7 +3987,25 @@ U32 LLVOVolume::getRenderCost(texture_cost_t &textures) const  		{  			if (textures.find(img->getID()) == textures.end())  			{ -				S32 texture_cost = 256 + (S32)(ARC_TEXTURE_COST * (img->getFullHeight() / 128.f + img->getFullWidth() / 128.f)); +                S32 texture_cost = 0; +                S8 type = img->getType(); +                if (type == LLViewerTexture::FETCHED_TEXTURE || type == LLViewerTexture::LOD_TEXTURE) +                { +                    const LLViewerFetchedTexture* fetched_texturep = static_cast<const LLViewerFetchedTexture*>(img); +                    if (fetched_texturep +                        && fetched_texturep->getFTType() == FTT_LOCAL_FILE +                        && (img->getID() == IMG_ALPHA_GRAD_2D || img->getID() == IMG_ALPHA_GRAD) +                        ) +                    { +                        // These two textures appear to switch between each other, but are of different sizes (4x256 and 256x256). +                        // Hardcode cost from larger one to not cause random complexity changes +                        texture_cost = 320; +                    } +                } +                if (texture_cost == 0) +                { +                    texture_cost = 256 + (S32)(ARC_TEXTURE_COST * (img->getFullHeight() / 128.f + img->getFullWidth() / 128.f)); +                }  				textures.insert(texture_cost_t::value_type(img->getID(), texture_cost));  			}  		} @@ -5450,8 +5468,8 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  	U32 useage = group->getSpatialPartition()->mBufferUsage; -	LLCachedControl<S32> max_vbo_size(gSavedSettings, "RenderMaxVBOSize", 512); -	LLCachedControl<S32> max_node_size(gSavedSettings, "RenderMaxNodeSize", 65536); +	static LLCachedControl<S32> max_vbo_size(gSavedSettings, "RenderMaxVBOSize", 512); +	static LLCachedControl<S32> max_node_size(gSavedSettings, "RenderMaxNodeSize", 65536);  	U32 max_vertices = (max_vbo_size * 1024)/LLVertexBuffer::calcVertexSize(group->getSpatialPartition()->mVertexDataMask);  	U32 max_total = (max_node_size * 1024) / LLVertexBuffer::calcVertexSize(group->getSpatialPartition()->mVertexDataMask);  	max_vertices = llmin(max_vertices, (U32) 65535); @@ -6217,7 +6235,7 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace  #endif  	//calculate maximum number of vertices to store in a single buffer -	LLCachedControl<S32> max_vbo_size(gSavedSettings, "RenderMaxVBOSize", 512); +	static LLCachedControl<S32> max_vbo_size(gSavedSettings, "RenderMaxVBOSize", 512);  	U32 max_vertices = (max_vbo_size * 1024)/LLVertexBuffer::calcVertexSize(group->getSpatialPartition()->mVertexDataMask);  	max_vertices = llmin(max_vertices, (U32) 65535); diff --git a/indra/newview/llwatchdog.cpp b/indra/newview/llwatchdog.cpp index 6273f10c69..0aa0280b25 100644 --- a/indra/newview/llwatchdog.cpp +++ b/indra/newview/llwatchdog.cpp @@ -31,15 +31,6 @@  const U32 WATCHDOG_SLEEP_TIME_USEC = 1000000; -void default_killer_callback() -{ -#ifdef LL_WINDOWS -	RaiseException(0,0,0,0); -#else -	raise(SIGQUIT); -#endif -} -  // This class runs the watchdog timing thread.  class LLWatchdogTimerThread : public LLThread  { @@ -158,11 +149,10 @@ void LLWatchdogTimeout::ping(const std::string& state)  }  // LLWatchdog -LLWatchdog::LLWatchdog() : -	mSuspectsAccessMutex(), -	mTimer(NULL), -	mLastClockCount(0), -	mKillerCallback(&default_killer_callback) +LLWatchdog::LLWatchdog() +    :mSuspectsAccessMutex() +    ,mTimer(NULL) +	,mLastClockCount(0)  {  } @@ -184,9 +174,8 @@ void LLWatchdog::remove(LLWatchdogEntry* e)  	unlockThread();  } -void LLWatchdog::init(killer_event_callback func) +void LLWatchdog::init()  { -	mKillerCallback = func;  	if(!mSuspectsAccessMutex && !mTimer)  	{  		mSuspectsAccessMutex = new LLMutex(); @@ -253,8 +242,7 @@ void LLWatchdog::run()  				mTimer->stop();  			} -			LL_INFOS() << "Watchdog detected error:" << LL_ENDL; -			mKillerCallback(); +            LL_ERRS() << "Watchdog timer expired; assuming viewer is hung and crashing" << LL_ENDL;  		}  	} diff --git a/indra/newview/llwatchdog.h b/indra/newview/llwatchdog.h index 9a6624258e..ce5cf748f4 100644 --- a/indra/newview/llwatchdog.h +++ b/indra/newview/llwatchdog.h @@ -83,9 +83,7 @@ public:  	void add(LLWatchdogEntry* e);  	void remove(LLWatchdogEntry* e); -	typedef boost::function<void (void)> killer_event_callback; - -	void init(killer_event_callback func = NULL); +	void init();  	void run();  	void cleanup(); @@ -98,8 +96,6 @@ private:  	LLMutex* mSuspectsAccessMutex;  	LLWatchdogTimerThread* mTimer;  	U64 mLastClockCount; - -	killer_event_callback mKillerCallback;  };  #endif // LL_LLTHREADWATCHDOG_H diff --git a/indra/newview/llweb.cpp b/indra/newview/llweb.cpp index 63257d6543..d019b400e8 100644 --- a/indra/newview/llweb.cpp +++ b/indra/newview/llweb.cpp @@ -237,7 +237,7 @@ bool LLWeb::useExternalBrowser(const std::string &url)  		up.extractParts();  		std::string uri_string = up.host(); -		boost::regex pattern = boost::regex("\\b(lindenlab.com|secondlife.com)$", boost::regex::perl|boost::regex::icase); +		boost::regex pattern = boost::regex("\\b(lindenlab.com|secondlife.com|secondlife.io)$", boost::regex::perl|boost::regex::icase);  		boost::match_results<std::string::const_iterator> matches;  		return !(boost::regex_search(uri_string, matches, pattern));  	} diff --git a/indra/newview/llwebprofile.cpp b/indra/newview/llwebprofile.cpp index a907245265..3cc82621c4 100644 --- a/indra/newview/llwebprofile.cpp +++ b/indra/newview/llwebprofile.cpp @@ -113,6 +113,7 @@ void LLWebProfile::uploadImageCoro(LLPointer<LLImageFormatted> image, std::strin      httpOpts->setWantHeaders(true);      httpOpts->setFollowRedirects(false); +    httpOpts->setSSLVerifyPeer(false); ; // viewer's cert bundle doesn't appear to agree with web certs from "https://my.secondlife.com/"      // Get upload configuration data.      std::string configUrl(getProfileURL(std::string()) + "snapshots/s3_upload_config"); diff --git a/indra/newview/llwlhandlers.cpp b/indra/newview/llwlhandlers.cpp index 730aa3774f..d55e1b7cd3 100644 --- a/indra/newview/llwlhandlers.cpp +++ b/indra/newview/llwlhandlers.cpp @@ -51,7 +51,7 @@ bool LLEnvironmentRequest::initiate(LLEnvironment::environment_apply_fn cb)  	if (!cur_region->capabilitiesReceived())  	{  		LL_INFOS("WindlightCaps") << "Deferring windlight settings request until we've got region caps" << LL_ENDL; -        cur_region->setCapabilitiesReceivedCallback([cb](const LLUUID ®ion_id) { LLEnvironmentRequest::onRegionCapsReceived(region_id, cb); }); +        cur_region->setCapabilitiesReceivedCallback([cb](const LLUUID ®ion_id, LLViewerRegion* regionp) { LLEnvironmentRequest::onRegionCapsReceived(region_id, cb); });  		return false;  	} diff --git a/indra/newview/llworldmipmap.cpp b/indra/newview/llworldmipmap.cpp index a2e519a61a..040d0deaf3 100644 --- a/indra/newview/llworldmipmap.cpp +++ b/indra/newview/llworldmipmap.cpp @@ -190,6 +190,8 @@ LLPointer<LLViewerFetchedTexture> LLWorldMipmap::loadObjectsTile(U32 grid_x, U32  	//LL_INFOS("WorldMap") << "LLWorldMipmap::loadObjectsTile(), URL = " << imageurl << LL_ENDL;  	LLPointer<LLViewerFetchedTexture> img = LLViewerTextureManager::getFetchedTextureFromUrl(imageurl, FTT_MAP_TILE, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); +	LL_INFOS("MAPURL") << "fetching map tile from " << imageurl << LL_ENDL; +  	img->setBoostLevel(LLGLTexture::BOOST_MAP);  	// Return the smart pointer diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml index 607f584fa6..1085972d9e 100644 --- a/indra/newview/skins/default/colors.xml +++ b/indra/newview/skins/default/colors.xml @@ -854,6 +854,9 @@      name="ColorSwatchBorderColor"      value="0.45098 0.517647 0.607843 1"/>      <color +     name="ChatTeleportSeparatorColor" +     reference="Black" /> +    <color       name="ChatTimestampColor"       reference="White" />      <color @@ -979,4 +982,7 @@    <color      name="OutfitGalleryItemUnselected"      value="0.4 0.4 0.4 1" /> +  <color +    name="AddPaymentPanel" +    value="0.27 0.27 0.27 1" />  </colors> diff --git a/indra/newview/skins/default/textures/icons/Inv_Toolbar_SearchVisibility.png b/indra/newview/skins/default/textures/icons/Inv_Toolbar_SearchVisibility.png Binary files differnew file mode 100644 index 0000000000..048da25c92 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Inv_Toolbar_SearchVisibility.png diff --git a/indra/newview/skins/default/textures/navbar/Landmarks.png b/indra/newview/skins/default/textures/navbar/Landmarks.png Binary files differnew file mode 100644 index 0000000000..2b35de913b --- /dev/null +++ b/indra/newview/skins/default/textures/navbar/Landmarks.png diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index ad9329dc65..7aa4ac511d 100644 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -45,6 +45,10 @@ with the same filename but different name    <texture name="AddItem_Off" file_name="icons/AddItem_Off.png" preload="false" />    <texture name="AddItem_Press" file_name="icons/AddItem_Press.png" preload="false" /> +  <texture name="add_payment_image_center"  file_name="windows/add_payment_image_center.png" preload="true" /> +  <texture name="add_payment_image_left"  file_name="windows/add_payment_image_left.png" preload="true" /> +  <texture name="add_payment_image_right"  file_name="windows/add_payment_image_right.png" preload="true" /> +    <texture name="Arrow_Left_Off" file_name="navbar/Arrow_Left_Off.png" preload="true" />    <texture name="Arrow_Right_Off" file_name="navbar/Arrow_Right_Off.png" preload="true" /> @@ -334,7 +338,11 @@ with the same filename but different name    <texture name="Inv_Unknown" file_name="icons/Inv_UnknownObject.png" preload="false" />    <texture name="Inv_VersionFolderClosed" file_name="icons/Inv_VersionFolderClosed.png" preload="false" />    <texture name="Inv_VersionFolderOpen" file_name="icons/Inv_VersionFolderOpen.png" preload="false" /> -   + +  <texture name="Inv_Toolbar_SearchVisibility" file_name="icons/Inv_Toolbar_SearchVisibility.png" preload="false" /> + +  <texture name="Landmarks_overlay" file_name="navbar/Landmarks.png" preload="false" /> +    <texture name="Linden_Dollar_Alert" file_name="widgets/Linden_Dollar_Alert.png"/>    <texture name="Linden_Dollar_Background" file_name="widgets/Linden_Dollar_Background.png"/> @@ -650,6 +658,7 @@ with the same filename but different name    <texture name="TextField_Search_Off" file_name="widgets/TextField_Search_Off.png" preload="true" scale.left="9" scale.top="12" scale.right="248" scale.bottom="12" />    <texture name="TextField_Disabled" file_name="widgets/TextField_Disabled.png" preload="true" scale.left="9" scale.top="12" scale.right="248" scale.bottom="12" />    <texture name="TextField_Active" file_name="widgets/TextField_Active.png" preload="true" scale.left="9" scale.top="12" scale.right="248" scale.bottom="12" /> +  <texture name="TextField_Search_Highlight" file_name="widgets/TextField_Search_Highlight.png" preload="true" scale.left="9" scale.top="12" scale.right="248" scale.bottom="12" />    <texture name="Toast_CloseBtn" file_name="windows/Toast_CloseBtn.png" preload="true" /> diff --git a/indra/newview/skins/default/textures/widgets/TextField_Search_Highlight.png b/indra/newview/skins/default/textures/widgets/TextField_Search_Highlight.png Binary files differnew file mode 100644 index 0000000000..e3944289c6 --- /dev/null +++ b/indra/newview/skins/default/textures/widgets/TextField_Search_Highlight.png diff --git a/indra/newview/skins/default/textures/windows/add_payment_image_center.png b/indra/newview/skins/default/textures/windows/add_payment_image_center.png Binary files differnew file mode 100644 index 0000000000..b5459136cb --- /dev/null +++ b/indra/newview/skins/default/textures/windows/add_payment_image_center.png diff --git a/indra/newview/skins/default/textures/windows/add_payment_image_left.png b/indra/newview/skins/default/textures/windows/add_payment_image_left.png Binary files differnew file mode 100644 index 0000000000..7fb65e724a --- /dev/null +++ b/indra/newview/skins/default/textures/windows/add_payment_image_left.png diff --git a/indra/newview/skins/default/textures/windows/add_payment_image_right.png b/indra/newview/skins/default/textures/windows/add_payment_image_right.png Binary files differnew file mode 100644 index 0000000000..f1937b6318 --- /dev/null +++ b/indra/newview/skins/default/textures/windows/add_payment_image_right.png diff --git a/indra/newview/skins/default/textures/windows/first_login_image_left.png b/indra/newview/skins/default/textures/windows/first_login_image_left.png Binary files differindex 1fa10fde53..77904d7d12 100644 --- a/indra/newview/skins/default/textures/windows/first_login_image_left.png +++ b/indra/newview/skins/default/textures/windows/first_login_image_left.png diff --git a/indra/newview/skins/default/textures/windows/first_login_image_right.png b/indra/newview/skins/default/textures/windows/first_login_image_right.png Binary files differindex d764d846b7..35ecce9c07 100644 --- a/indra/newview/skins/default/textures/windows/first_login_image_right.png +++ b/indra/newview/skins/default/textures/windows/first_login_image_right.png diff --git a/indra/newview/skins/default/xui/en/floater_add_payment_method.xml b/indra/newview/skins/default/xui/en/floater_add_payment_method.xml new file mode 100644 index 0000000000..1f980564d4 --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_add_payment_method.xml @@ -0,0 +1,140 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater + height="405" + width="900" + layout="topleft" + name="floater_add_payment_method" + single_instance="true" + show_title="false" + legacy_header_height="0" + header_height="0" + background_visible="false" + can_resize="false" + can_drag_on_left="false" + can_minimize="false" + can_close="false"> +  <floater.string +    name="continue_url"> +    https://secondlife.com/my/lindex/buy.php?associate_for_viewer=1 +  </floater.string> +  <panel +   background_opaque="false" +   bg_alpha_color="AddPaymentPanel" +   border_visible="false" +   background_visible="true" +   label="wrapper_panel" +   layout="topleft" +   left="0" +   name="wrapper_panel" +   top="0" +   height="405" +   width="900" +   follows="all" +   translate="false"> +    <text +     type="string" +     length="1" +     follows="top|left|right" +     font="SansSerifLargeBold" +     text_color="White" +     layout="topleft" +     left="0" +     height="14" +     top_pad="30" +     width="900" +     halign="center" +     name="title_txt"> +      Add a payment method to buy Linden dollars and enjoy more of Second Life. +    </text> +    <button +     follows="top|left|right" +     height="24" +     label="Get started" +     font="SansSerifMedium" +     layout="topleft" +     left="320" +     name="continue_btn" +     image_unselected="PushButton_Login" +     image_pressed="PushButton_Login_Pressed" +     image_hover_unselected="PushButton_Login_Over" +     label_color="White" +     top_pad ="15" +     width="140"/> +    <button +     follows="top|left|right" +     height="24" +     label="Later" +     layout="topleft" +     left_pad="9" +     name="close_btn" +     width="90"/> +    <icon +     height="195" +     width="260"  +     image_name="add_payment_image_left" +     layout="topleft" +     left="30" +     name="image_left" +     top_pad="30" +     use_draw_context_alpha="false"/> +    <icon +     height="195" +     width="260" +     image_name="add_payment_image_center" +     layout="topleft" +     left_pad="30" +     name="image_center" +     use_draw_context_alpha="false"/> +    <icon +     height="195" +     width="260" +     image_name="add_payment_image_right" +     layout="topleft" +     left_pad="30" +     name="image_right" +     use_draw_context_alpha="false"/> +    <text +     type="string" +     length="1" +     follows="top|left" +     font="SansSerifMedium" +     text_color="White" +     height="75" +     width="260" +     top_pad="15" +     layout="topleft" +     word_wrap="true" +     left="30" +     name="image_left_desc"> +      Create an avatar you love. Choose from millions of items in stores and the Second Life Marketplace. Your style is here. +    </text> +    <text +     type="string" +     length="1" +     follows="top|left" +     font="SansSerifMedium" +     text_color="White" +     height="75" +     width="260" +     layout="topleft" +     word_wrap="true" +     left_pad="30" +     name="image_center_desc"> +      Donate to your favorite performers and hosts. Your support helps them create great experiences. +    </text> +    <text +     type="string" +     length="1" +     follows="top|left" +     font="SansSerifMedium" +     text_color="White" +     height="75" +     width="260" +     layout="topleft" +     word_wrap="true" +     left_pad="30" +     name="image_right_desc"> +      Make the home of your dreams. With millions of items available to purchase, you can make your retreat unique. +    </text> +  </panel> +</floater> diff --git a/indra/newview/skins/default/xui/en/floater_adjust_environment.xml b/indra/newview/skins/default/xui/en/floater_adjust_environment.xml index 59589e3665..f4a686bae1 100644 --- a/indra/newview/skins/default/xui/en/floater_adjust_environment.xml +++ b/indra/newview/skins/default/xui/en/floater_adjust_environment.xml @@ -5,14 +5,14 @@           save_rect="false"           title="Personal Lighting"           width="845" -         height="240" +         height="280"           min_width="500" -         min_height="235" +         min_height="275"           single_instance="true"           can_resize="false">      <layout_stack name="outer_stack"                    width="845" -                  height="230" +                  height="275"                    follows="all"                    animate="false"                    top="0" @@ -276,19 +276,57 @@                                          height="150"                                          width="150"                                          thumb_mode="sun"/> +                  <text follows="left|top" +                        height="10" +                        layout="topleft" +                        left_delta="0" +                        top_pad="5" +                        width="200">Azimuth:</text> +                  <slider decimal_digits="2" +                          follows="left|top" +                          height="16" +                          increment="0.01" +                          initial_value="0" +                          layout="topleft" +                          left_delta="5" +                          min_val="0" +                          max_val="359.99" +                          name="sun_azimuth" +                          top_pad="5" +                          width="130" +                          can_edit_text="true"/> +                  <text follows="left|top" +                        height="10" +                        layout="topleft" +                        left_delta="-5" +                        top_pad="5" +                        width="200">Elevation:</text> +                  <slider decimal_digits="2" +                          follows="left|top" +                          height="16" +                          increment="0.01" +                          initial_value="0" +                          layout="topleft" +                          left_delta="5" +                          min_val="-90" +                          max_val="90" +                          name="sun_elevation" +                          top_pad="5" +                          width="130" +                          can_edit_text="true"/>                      <check_box control_name="sunbeacon"                                 width="60"                                 height="16"                                 label="Show Beacon"                                 layout="topleft"                                 name="sunbeacon" -                               left_delta="55" -                               bottom="-20" -                               follows="bottom|right"/> +                               left_delta="-5" +                               top_pad="8" +                               follows="left|top"/>                      <text follows="left|top"                            height="10"                            layout="topleft" -                          left_pad="40" +                          left_pad="95"                            top="25"                            width="80">Scale:</text>                      <slider decimal_digits="2" @@ -385,15 +423,53 @@                                          height="150"                                          width="150"                                          thumb_mode="moon"/> +                  <text follows="left|top" +                        height="10" +                        layout="topleft" +                        left_delta="0" +                        top_pad="5" +                        width="200">Azimuth:</text> +                  <slider decimal_digits="2" +                          follows="left|top" +                          height="16" +                          increment="0.01" +                          initial_value="0" +                          layout="topleft" +                          left_delta="5" +                          min_val="0" +                          max_val="359.99" +                          name="moon_azimuth" +                          top_pad="5" +                          width="130" +                          can_edit_text="true"/> +                  <text follows="left|top" +                        height="10" +                        layout="topleft" +                        left_delta="-5" +                        top_pad="5" +                        width="200">Elevation:</text> +                  <slider decimal_digits="2" +                          follows="left|top" +                          height="16" +                          increment="0.01" +                          initial_value="0" +                          layout="topleft" +                          left_delta="5" +                          min_val="-90" +                          max_val="90" +                          name="moon_elevation" +                          top_pad="5" +                          width="130" +                          can_edit_text="true"/>                      <check_box control_name="moonbeacon" +                               follows="left|top"                                 width="60"                                 height="16"                                 label="Show Beacon"                                 layout="topleft"                                 name="moonbeacon" -                               right="-50" -                               bottom="-20" -                               follows="bottom|right"/> +                               left_delta="0" +                               top_pad="8"/>                  </layout_panel>              </layout_stack>          </layout_panel> diff --git a/indra/newview/skins/default/xui/en/floater_avatar.xml b/indra/newview/skins/default/xui/en/floater_avatar.xml index 92c5d8bcbe..3df2683ca8 100644 --- a/indra/newview/skins/default/xui/en/floater_avatar.xml +++ b/indra/newview/skins/default/xui/en/floater_avatar.xml @@ -14,7 +14,7 @@   help_topic="avatar"   save_rect="true"   save_visibility="true" - title="CHOOSE AN AVATAR" + title="COMPLETE AVATARS"   width="700">      <web_browser        top="25" diff --git a/indra/newview/skins/default/xui/en/floater_buy_currency.xml b/indra/newview/skins/default/xui/en/floater_buy_currency.xml index 061af1b67c..e8e83301be 100644 --- a/indra/newview/skins/default/xui/en/floater_buy_currency.xml +++ b/indra/newview/skins/default/xui/en/floater_buy_currency.xml @@ -1,8 +1,8 @@  <?xml version="1.0" encoding="UTF-8" standalone="yes"?>  <floater - legacy_header_height="18" +   can_minimize="false" - height="275" + height="285"   layout="topleft"   title="BUY L$"   name="buy currency" @@ -17,277 +17,385 @@       name="info_cannot_buy">          Unable to Buy      </floater.string> +    <floater.string +     name="estimated_zero"> +        US$ 0.00 +    </floater.string>      <icon -     height="215" +     height="245"       image_name="Linden_Dollar_Background"       layout="topleft"       left="0"       name="normal_background" -     top="17" +     top="0"       use_draw_context_alpha="false"       width="350" /> -   <text -     type="string" -     length="1" -     follows="top|left|right" -     font="SansSerifHuge" -     layout="topleft" -     left="20" -     height="30" -     top="25" -     width="340" -     name="info_need_more"> -        You need more L$ -    </text> -    <text -     type="string" -     length="1" -     follows="top|left" -     height="16" +  <layout_stack +    animate="false" +    name="outer_stack" +    layout="topleft" +    follows="all" +    orientation="vertical" +    left="0" +    top="0" +    width="350" +    height="285"> +    <layout_panel +     auto_resize="false" +     name="layout_panel_title"       layout="topleft" -     top="246" -     left="15" -     width="300" -     name="contacting"> -        Contacting LindeX... -    </text> -    <text -     type="string" -     length="1" -     follows="top|left" -     font="SansSerifHuge" +     follows="all" +     width="350" +     height="35"> +      <text +       type="string" +       length="1" +       follows="top|left|right" +       font="SansSerifLarge" +       layout="topleft" +       left="20" +       height="30" +       top="8" +       width="340" +       name="info_need_more"> +          You need more L$ +      </text> +      <text +       type="string" +       length="1" +       follows="top|left|right" +       font="SansSerifLarge" +       layout="topleft" +       left="20" +       height="30" +       top="8" +       width="300" +       name="info_buying"> +          Buy L$ +      </text> +      <view_border +       bevel_style="none" +       height="0" +       layout="topleft" +       left="20" +       name="text_border" +       top_delta="25" +       width="300"/> +    </layout_panel> +    <layout_panel +     auto_resize="false" +     name="layout_panel_price"       layout="topleft" -     left="20" -     height="30" -     top="25" -     width="300" -     name="info_buying"> -        Buy L$ -    </text> -    <text -     type="string" -     length="1" -     follows="top|left" -     font="SansSerifMedium" -     height="16" +     follows="all" +     width="350" +     height="18"> +      <text +       type="string" +       length="1" +       follows="top|left" +       font="SansSerifMedium" +       height="16" +       layout="topleft" +       left="20" +       name="target_price_label" +       top_pad="3" +       width="210"> +          You need +      </text> +      <text +       type="string" +       length="1" +       font="SansSerifMedium" +       follows="top|left" +       halign="right" +       height="16" +       layout="topleft" +       left="200" +       name="target_price" +       top_delta="0" +       width="120"> +          L$ [AMT] +      </text> +    </layout_panel> +    <layout_panel +     auto_resize="false" +     name="layout_panel_balance"       layout="topleft" -     left="20" -     name="balance_label" -     top="65" -     width="210"> -        I have -    </text> -    <text -     type="string" -     length="1" -     font="SansSerifMedium" -     follows="top|left" -     halign="right" -     height="16" -     layout="topleft" -     left="200" -     name="balance_amount" -     top_delta="0" -     width="120"> +     follows="all" +     width="350" +     height="19"> +      <text +       type="string" +       length="1" +       follows="top|left" +       font="SansSerifMedium" +       height="16" +       layout="topleft" +       left="20" +       name="balance_label" +       top_pad="5" +       width="210"> +        You now have +      </text> +      <text +       type="string" +       length="1" +       font="SansSerifMedium" +       follows="top|left" +       halign="right" +       height="16" +       layout="topleft" +       left="200" +       name="balance_amount" +       top_delta="0" +       width="120">          L$ [AMT] -    </text> -    <text -     type="string" -     length="1" -     follows="top|left" -     font="SansSerifMedium" -     height="16" -     top="95" -     layout="topleft" -     left="20" -     name="currency_action" -     width="210"> -        I want to buy -    </text> -    <text -     font="SansSerifMedium" -     type="string" -     length="1" -     follows="left|top" -     height="16" -     layout="topleft" -     top_delta="0" -     left="217" -     name="currency_label" -     width="15"> -      L$ -    </text> -    <line_editor -     type="string" -     max_length_bytes="10" -     halign="right" -     font="SansSerifMedium" -     select_on_focus="true" -     follows="top|left" -     top_delta="-7" -     height="22" -     label="L$" -     left_pad="3" -     name="currency_amt" -     width="85"> -        1234 -    </line_editor> -    <text -     type="string" -     font="SansSerifMedium" -     length="1" -     follows="top|left" -     height="16" -     layout="topleft" -     left="20" -     top="125" -     name="buying_label" -     width="210"> -        For the price -    </text> -    <text -     type="string" -     length="1" -     font="SansSerifMedium" -     text_color="EmphasisColor" -     follows="top|left" -     halign="right" -     height="16" -     top_delta="0" +      </text> +    </layout_panel> +    <layout_panel +     auto_resize="false" +     name="layout_panel_required"       layout="topleft" -     left="150" -     name="currency_est" -     width="170"> -     approx. [LOCALAMOUNT] -    </text> -    <text -     type="string" -     font="SansSerifSmall" -     text_color="EmphasisColor" -     length="1" -     follows="top|left" -     height="16" -     layout="topleft" -     top="125" -     left="170" -     width="150" -     halign="right" -     name="getting_data"> -        Estimating... -    </text> -    <text -     type="string" -     font="SansSerifSmall" -     top="145" -     length="1" -     follows="top|left" -     height="16" -     halign="right" -     left="20" -     width="300" -     layout="topleft" -     name="buy_action"> -        [ACTION] -    </text> -    <text -     type="string" -     font="SansSerifMedium" -     length="1" -     follows="top|left" -     height="16" -     layout="topleft" -     left="20" -     name="total_label" -     top="165" -     width="210"> -        My new balance will be -    </text> -    <text -     type="string" -     length="1" -     font="SansSerifMedium" -     follows="top|left" -     top_delta="0" -     height="16" -     layout="topleft" -     left="200" -     halign="right" -     name="total_amount" -     width="120"> +     follows="all" +     width="350" +     height="22"> +      <text +        type="string" +        length="1" +        follows="top|left" +        font="SansSerifMedium" +        font.style="BOLD" +        height="16" +        layout="topleft" +        left="20" +        name="required_label" +        top_pad="6" +        width="210"> +        You should buy at least +      </text> +      <text +       type="string" +       length="1" +       font="SansSerifMedium" +       follows="top|left" +       halign="right" +       height="16" +       layout="topleft" +       left="200" +       name="required_amount" +       top_delta="0" +       width="120">          L$ [AMT] -    </text> -    <text -     type="string" -     length="1" -     text_color="LtGray_50" -     follows="top|left" +      </text> +    </layout_panel> +    <layout_panel +     auto_resize="false" +     name="layout_panel_action"       layout="topleft" -     halign="right" -     top="189" -     left="20" -     width="300" -     height="30" -     name="currency_links"> -      [http://www.secondlife.com/my/account/payment_method_management.php payment method] | [http://www.secondlife.com/my/account/currency.php currency] -    </text> -    <text -     type="string" -     length="1" -     text_color="LtGray_50" -     follows="top|left" +     follows="all" +     width="350" +     height="90"> +      <view_border +       bevel_style="none" +       height="0" +       layout="topleft" +       left="20" +       name="text_border_2" +       top_pad="5" +       width="300"/> +      <text +       type="string" +       length="1" +       follows="top|left" +       font="SansSerifMedium" +       height="16" +       top_pad="15" +       layout="topleft" +       left="20" +       name="currency_action" +       width="210"> +          Choose amount to buy +      </text> +      <text +       font="SansSerifMedium" +       type="string" +       length="1" +       follows="left|top" +       height="16" +       layout="topleft" +       top_delta="0" +       left="247" +       name="currency_label" +       width="15"> +        L$ +      </text> +      <line_editor +       type="string" +       max_length_bytes="10" +       halign="right" +       font="SansSerifMedium" +       select_on_focus="true" +       follows="top|left" +       top_delta="-4" +       height="22" +       label="L$" +       left_pad="3" +       name="currency_amt" +       width="55"> +          1234 +      </line_editor> +      <text +       type="string" +       length="1" +       font="SansSerifMedium" +       text_color="EmphasisColor" +       follows="top|left" +       halign="right" +       height="16" +       top_pad="4" +       layout="topleft" +       left="150" +       name="currency_est" +       width="170"> +       Approx. [LOCALAMOUNT] +      </text> +      <text +       type="string" +       font="SansSerifSmall" +       text_color="EmphasisColor" +       length="1" +       follows="top|left" +       height="16" +       layout="topleft" +       left="170" +       top_delta="0" +       width="150" +       halign="right" +       name="getting_data"> +          Estimating... +      </text> +      <text +       type="string" +       font="SansSerifMedium" +       length="1" +       follows="top|left" +       height="16" +       layout="topleft" +       left="20" +       name="total_label" +       top_pad="10" +       width="210"> +          Your new balance will be +      </text> +      <text +       type="string" +       length="1" +       font="SansSerifMedium" +       follows="top|left" +       top_delta="0" +       height="16" +       layout="topleft" +       left="200" +       halign="right" +       name="total_amount" +       width="120"> +          L$ [AMT] +      </text> +    </layout_panel> +    <layout_panel +     auto_resize="false" +     name="layout_panel_msg"       layout="topleft" -     halign="right" -     top="202" -     left="20" -     width="300" -     height="30" -     name="exchange_rate_note"> +     follows="all" +     width="350" +     height="50"> +      <view_border +       bevel_style="none" +       height="0" +       layout="topleft" +       left="20" +       name="text_border_3" +       top_pad="0" +       width="300"/> +      <text +       type="string" +       length="1" +       text_color="LtGray_50" +       follows="top|left" +       layout="topleft" +       halign="right" +       top_pad="3" +       left="20" +       width="300" +       height="30" +       name="currency_links"> +        [http://www.secondlife.com/my/account/payment_method_management.php payment method] | [http://www.secondlife.com/my/account/currency.php currency] +      </text> +      <text +       type="string" +       length="1" +       text_color="LtGray_50" +       follows="top|left" +       layout="topleft" +       halign="right" +       top="19" +       left="20" +       width="300" +       height="30" +       name="exchange_rate_note">  Re-enter amount to see the latest exchange rate. -    </text> -    <text -     type="string" -     length="1" -     text_color="LtGray_50" -     follows="top|left" -     layout="topleft" -     halign="right" -     top="208" -     left="10" -     width="310" -     height="35" -     name="purchase_warning_repurchase"> -        Confirming this purchase only buys L$, not the object. -    </text> -    <text -     type="string" -     length="1" -     text_color="LtGray_50" -     follows="top|left" -     layout="topleft" -     halign="right" -     top="213" -     left="20" -     width="300" -     height="30" -     name="purchase_warning_notenough"> -        You aren't buying enough L$. Please increase the amount. -    </text> - -    <button -     follows="bottom|left" -     height="20" -     label="Buy Now" -     layout="topleft" -     left="151" -     name="buy_btn" -     top="242" -     width="90"/> -    <button -     follows="bottom|right" -     height="20" -     label="Cancel" +      </text> +      <text +       type="string" +       length="1" +       follows="top|left" +       layout="topleft" +       font="SansSerifMedium" +       top="10" +       left="20" +       width="310" +       height="35" +       name="purchase_warning_repurchase"> +After you receive your L$, you should try your +purchase again. +      </text> +    </layout_panel> +    <layout_panel +     auto_resize="false" +     name="layout_panel_buttons"       layout="topleft" -     left_pad="10" -     name="cancel_btn" -     width="90"/> +     follows="all" +     width="350" +     height="40"> +      <text +       type="string" +       length="1" +       follows="top|left" +       height="16" +       layout="topleft" +       top_pad="0" +       left="15" +       width="300" +       name="contacting"> +          Contacting LindeX... +        </text> +      <button +       follows="top|left|right" +       height="20" +       label="Buy L$ now" +       layout="topleft" +       left="151" +       name="buy_btn" +       bottom_delta ="8" +       width="90"/> +      <button +       follows="top|left|right" +       height="20" +       label="Cancel" +       layout="topleft" +       left_pad="10"      +       name="cancel_btn" +       width="90"/> +    </layout_panel> +  </layout_stack>  </floater> diff --git a/indra/newview/skins/default/xui/en/floater_create_landmark.xml b/indra/newview/skins/default/xui/en/floater_create_landmark.xml new file mode 100644 index 0000000000..bba30626b2 --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_create_landmark.xml @@ -0,0 +1,113 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater + can_resize="false" + show_title="false" + can_minimize="false" + can_close="false" + header_height="10" + bg_opaque_image="Window_NoTitle_Foreground" + bg_alpha_image="Window_NoTitle_Background" + height="305" + layout="topleft" + name="create_landmark" + width="330"> +  <string name="favorites_bar"> +    Favorites bar +  </string> +    <text +     follows="left|top" +     height="15" +     layout="topleft" +     left="20" +     name="title_label" +     top="5" +     font="SansSerifLargeBold" +     value="Landmark added" +     width="290" /> +    <text +     follows="left|top" +     height="15" +     layout="topleft" +     left="20" +     name="name_label" +     top_pad="10" +     value="Name" +     width="290" /> +    <line_editor +     follows="left|top" +     height="22" +     layout="topleft" +     max_length_bytes="63" +     name="title_editor" +     prevalidate_callback="ascii" +     text_readonly_color="white" +     top_pad="5" +     width="290" /> +    <text +     follows="left|top" +     height="15" +     layout="topleft" +     name="folder_label" +     top_pad="10" +     value="Save this landmark in:" +     width="290" /> +    <combo_box +     follows="bottom|left" +     height="23" +     layout="topleft" +     name="folder_combo" +     top_pad="2" +     width="290" /> +    <text +     follows="left|top" +     layout="topleft" +     top_pad="6" +     left="20" +     name="new_folder_textbox" +     height="20" +     parse_urls="true" +     skip_link_underline="true" +     wrap="true"> +        [secondlife:/// Create new folder] +    </text> +    <text +     follows="left|top" +     height="15" +     layout="topleft" +     name="notes_label" +     top_pad="10" +     value="My notes" +     width="290" /> +    <text_editor +     bg_readonly_color="DkGray0" +     follows="all" +     height="75" +     layout="topleft" +     max_length="127" +     name="notes_editor" +     spellcheck="true" +     text_readonly_color="white" +     text_type="ascii_with_newline" +     top_pad="5" +     width="290" +     wrap="true" /> +    <button +     follows="bottom|left|right" +     height="23" +     label="OK" +     layout="topleft" +     mouse_opaque="false" +     name="ok_btn" +     top_pad="10" +     left="19" +     width="140" /> +    <button +     follows="bottom|left|right" +     height="23" +     label="Cancel" +     layout="topleft" +     left_pad="12" +     mouse_opaque="false" +     name="cancel_btn" +     width="140" /> +</floater> diff --git a/indra/newview/skins/default/xui/en/floater_edit_ext_day_cycle.xml b/indra/newview/skins/default/xui/en/floater_edit_ext_day_cycle.xml index 30e9002230..c609e3bd3a 100644 --- a/indra/newview/skins/default/xui/en/floater_edit_ext_day_cycle.xml +++ b/indra/newview/skins/default/xui/en/floater_edit_ext_day_cycle.xml @@ -616,7 +616,7 @@                      follows="top|left"                      height="23"                      label="Save" -                    left="5" +                    left="200"                      top_pad="0"                      name="save_btn"                      width="156" /> diff --git a/indra/newview/skins/default/xui/en/floater_fixedenvironment.xml b/indra/newview/skins/default/xui/en/floater_fixedenvironment.xml index dbf91b0834..a6e20880a9 100644 --- a/indra/newview/skins/default/xui/en/floater_fixedenvironment.xml +++ b/indra/newview/skins/default/xui/en/floater_fixedenvironment.xml @@ -89,7 +89,7 @@                  follows="left|top|right|bottom"                  auto_resize="false"                  user_resize="false" -                height="40" +                height="29"                  visible="true">              <layout_stack                      follows="bottom|left|right" @@ -97,7 +97,7 @@                      layout="topleft"                      mouse_opaque="false"                      name="button_bar_ls" -                    left="0" +                    left="212"                      orientation="horizontal"                      top="0"                      width="313"> diff --git a/indra/newview/skins/default/xui/en/floater_how_to.xml b/indra/newview/skins/default/xui/en/floater_how_to.xml index 8c0077a8cc..baff8e1bc0 100644 --- a/indra/newview/skins/default/xui/en/floater_how_to.xml +++ b/indra/newview/skins/default/xui/en/floater_how_to.xml @@ -1,18 +1,17 @@  <?xml version="1.0" encoding="utf-8" standalone="yes" ?>  <floater    legacy_header_height="18" -  can_resize="true" -  can_minimize="true"  -  height="775" +  can_resize="false" +  can_minimize="false" +  can_close="false" +  height="525"    layout="topleft" -  min_height="360" -  left="10000" -  top="10"  -  min_width="335"    name="floater_how_to" -  help_topic="how_to"    single_instance="true" +  save_visibility="true"    save_rect="true" -  title="HOW TO" -  width="780" +  title="WELCOME ISLAND GUIDEBOOK" +  width="310" +  rel_x="-0.469309" +  rel_y="-0.011166"    filename="floater_web_content.xml"/>
\ No newline at end of file diff --git a/indra/newview/skins/default/xui/en/floater_model_preview.xml b/indra/newview/skins/default/xui/en/floater_model_preview.xml index 02a21764ce..7f863756eb 100644 --- a/indra/newview/skins/default/xui/en/floater_model_preview.xml +++ b/indra/newview/skins/default/xui/en/floater_model_preview.xml @@ -1362,7 +1362,7 @@           top_pad="9"           left="6"           width="70" -         label="Enable detailed logging" +         label="Enable detailed logging (can be very slow)"           name="verbose_logging"/>        </panel>      </tab_container> diff --git a/indra/newview/skins/default/xui/en/floater_my_appearance.xml b/indra/newview/skins/default/xui/en/floater_my_appearance.xml index fdea7a821a..35ad87ceb0 100644 --- a/indra/newview/skins/default/xui/en/floater_my_appearance.xml +++ b/indra/newview/skins/default/xui/en/floater_my_appearance.xml @@ -11,7 +11,7 @@    save_rect="true"    single_instance="true"    reuse_instance="true" -  title="APPEARANCE" +  title="AVATAR"    min_height="440"    min_width="333"    width="333"> diff --git a/indra/newview/skins/default/xui/en/floater_my_scripts.xml b/indra/newview/skins/default/xui/en/floater_my_scripts.xml index 3b0b6723c7..ee6defce9d 100644 --- a/indra/newview/skins/default/xui/en/floater_my_scripts.xml +++ b/indra/newview/skins/default/xui/en/floater_my_scripts.xml @@ -7,7 +7,7 @@   layout="topleft"   name="myscripts"   save_rect="true" - title="My Scripts" + title="ATTACHMENT SCRIPTS"   min_width="620"   width="620">    <panel diff --git a/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml b/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml index 3cc99b28c9..7786ba8a1c 100644 --- a/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml +++ b/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml @@ -626,23 +626,6 @@      top_delta="16"      width="300" /> -  <!-- SL-12594, basic shaders always enabled, no fixed-function GL  -  <check_box -    control_name="VertexShaderEnable" -    height="16" -    initial_value="true" -    label="Basic shaders" -    layout="topleft" -    left="420" -    name="BasicShaders" -    tool_tip="Disabling this option may prevent some graphics card drivers from crashing" -    top_delta="16" -    width="300"> -    <check_box.commit_callback -      function="Pref.VertexShaderEnable" /> -  </check_box> -  --> -        <slider      control_name="RenderTerrainDetail"      follows="left|top" diff --git a/indra/newview/skins/default/xui/en/floater_url_entry.xml b/indra/newview/skins/default/xui/en/floater_url_entry.xml index 29fb29fabf..2dfc0fd125 100644 --- a/indra/newview/skins/default/xui/en/floater_url_entry.xml +++ b/indra/newview/skins/default/xui/en/floater_url_entry.xml @@ -66,7 +66,7 @@       layout="topleft"       left="152"       name="loading_label" -     visible="true"> +     visible="false">          Loading...      </text>  </floater> diff --git a/indra/newview/skins/default/xui/en/menu_attachment_other.xml b/indra/newview/skins/default/xui/en/menu_attachment_other.xml index 38f4b7715f..7ad692038e 100644 --- a/indra/newview/skins/default/xui/en/menu_attachment_other.xml +++ b/indra/newview/skins/default/xui/en/menu_attachment_other.xml @@ -173,16 +173,13 @@            parameter="avatar_render_settings" />        </menu_item_call>        </context_menu> -  <menu_item_separator -       layout="topleft" name="Impostor seperator"/> -    <menu_item_call       enabled="false"       label="Block Particle Owner"       name="Mute Particle">      <menu_item_call.on_click       function="Particle.Mute" /> -    <menu_item_call.on_enable +    <menu_item_call.on_visible       function="EnableMuteParticle" />    </menu_item_call>  </context_menu> diff --git a/indra/newview/skins/default/xui/en/menu_attachment_self.xml b/indra/newview/skins/default/xui/en/menu_attachment_self.xml index 59faf6a9f5..26b1c86c53 100644 --- a/indra/newview/skins/default/xui/en/menu_attachment_self.xml +++ b/indra/newview/skins/default/xui/en/menu_attachment_self.xml @@ -4,28 +4,7 @@   name="Attachment Pie">      <menu_item_call       enabled="false" -     label="Touch" -     layout="topleft" -     name="Attachment Object Touch"> -        <menu_item_call.on_click -         function="Object.Touch" /> -        <menu_item_call.on_enable -         function="Object.EnableTouch" -         name="EnableTouch"/> -    </menu_item_call> -    <!--menu_item_call -     label="Stand Up" -     layout="topleft" -     name="Stand Up"> -        <menu_item_call.on_click -         function="Self.StandUp" -         parameter="" /> -        <menu_item_call.on_enable -         function="Self.EnableStandUp" /> -    </menu_item_call--> -    <menu_item_call -     enabled="false" -     label="Edit" +     label="Edit item"       layout="topleft"       name="Edit...">          <menu_item_call.on_click @@ -35,7 +14,7 @@      </menu_item_call>      <menu_item_call       enabled="false" -     label="Detach" +     label="Detach item"       layout="topleft"       name="Detach">          <menu_item_call.on_click @@ -43,98 +22,278 @@          <menu_item_call.on_enable           function="Attachment.EnableDetach" />      </menu_item_call> -  <menu_item_separator -    layout="topleft" /> -      <menu_item_call -     label="Sit Down" +     enabled="false" +     label="Touch item"       layout="topleft" -     name="Sit Down Here"> +     name="Attachment Object Touch">          <menu_item_call.on_click -         function="Self.SitDown" -         parameter="" /> +         function="Object.Touch" />          <menu_item_call.on_enable -         function="Self.EnableSitDown" /> +         function="Object.EnableTouch" +         name="EnableTouch"/>      </menu_item_call> +    <menu_item_separator +     layout="topleft" />    <menu_item_call -label="Stand Up" -layout="topleft" -name="Stand Up"> +  label="Now wearing..." +  name="NowWearing">      <menu_item_call.on_click -     function="Self.StandUp" -     parameter="" /> +     function="NowWearing" />      <menu_item_call.on_enable -     function="Self.EnableStandUp" /> +     function="Edit.EnableCustomizeAvatar" />    </menu_item_call>    <menu_item_call -  label="My Appearance" +  label="My Outfits..."    name="Change Outfit">      <menu_item_call.on_click       function="CustomizeAvatar" />      <menu_item_call.on_enable       function="Edit.EnableCustomizeAvatar" />    </menu_item_call> -  <menu_item_call label="Edit My Outfit" -layout="topleft" -name="Edit Outfit"> +  <menu_item_call label="Hover height..." +     layout="topleft" +     name="Hover Height">      <menu_item_call.on_click -     function="EditOutfit" /> +     function="HoverHeight" />      <menu_item_call.on_enable -     function="Edit.EnableCustomizeAvatar" /> +     function="Edit.EnableHoverHeight" />    </menu_item_call> -  <menu_item_call label="Edit My Shape" +  <menu_item_call label="Shape..."      layout="topleft" -    name="Edit My Shape"> +    name="Edit Shape">      <menu_item_call.on_click       function="EditShape" />      <menu_item_call.on_enable       function="Edit.EnableEditShape" />    </menu_item_call> -  <menu_item_call label="Hover Height" -     layout="topleft" -     name="Hover Height"> -     <menu_item_call.on_click -      function="HoverHeight" /> -     <menu_item_call.on_enable -      function="Edit.EnableHoverHeight" /> +  <menu_item_call label="Edit outfit parts..." +    layout="topleft" +    name="Edit Outfit"> +    <menu_item_call.on_click +     function="EditOutfit" /> +    <menu_item_call.on_enable +     function="Edit.EnableCustomizeAvatar" />    </menu_item_call> -  <menu_item_call label="Reset Skeleton" +  <context_menu +  label="Take off" +  layout="topleft" +  name="Take Off >"> +    <context_menu +     label="Clothes" +     layout="topleft" +     name="Clothes >"> +      <menu_item_call +       enabled="false" +       label="Shirt"         layout="topleft" -       name="Reset Skeleton"> -       <menu_item_call.on_click -        function="Avatar.ResetSkeleton" /> -  </menu_item_call> -  <menu_item_call label="Reset Skeleton And Animations" +       name="Shirt"> +        <menu_item_call.on_click +         function="Edit.TakeOff" +         parameter="shirt" /> +        <menu_item_call.on_enable +         function="Edit.EnableTakeOff" +         parameter="shirt" /> +      </menu_item_call> +      <menu_item_call +       enabled="false" +       label="Pants"         layout="topleft" -       name="Reset Skeleton And Animations"> -       <menu_item_call.on_click -        function="Avatar.ResetSkeletonAndAnimations" /> -  </menu_item_call> - +       name="Pants"> +        <menu_item_call.on_click +         function="Edit.TakeOff" +         parameter="pants" /> +        <menu_item_call.on_enable +         function="Edit.EnableTakeOff" +         parameter="pants" /> +      </menu_item_call> +      <menu_item_call +       enabled="false" +       label="Skirt" +       layout="topleft" +       name="Skirt"> +        <menu_item_call.on_click +         function="Edit.TakeOff" +         parameter="skirt" /> +        <menu_item_call.on_enable +         function="Edit.EnableTakeOff" +         parameter="skirt" /> +      </menu_item_call> +      <menu_item_call +       enabled="false" +       label="Shoes" +       layout="topleft" +       name="Shoes"> +        <menu_item_call.on_click +         function="Edit.TakeOff" +         parameter="shoes" /> +        <menu_item_call.on_enable +         function="Edit.EnableTakeOff" +         parameter="shoes" /> +      </menu_item_call> +      <menu_item_call +       enabled="false" +       label="Socks" +       layout="topleft" +       name="Socks"> +        <menu_item_call.on_click +         function="Edit.TakeOff" +         parameter="socks" /> +        <menu_item_call.on_enable +         function="Edit.EnableTakeOff" +         parameter="socks" /> +      </menu_item_call> +      <menu_item_call +       enabled="false" +       label="Jacket" +       layout="topleft" +       name="Jacket"> +        <menu_item_call.on_click +         function="Edit.TakeOff" +         parameter="jacket" /> +        <menu_item_call.on_enable +         function="Edit.EnableTakeOff" +         parameter="jacket" /> +      </menu_item_call> +      <menu_item_call +       enabled="false" +       label="Gloves" +       layout="topleft" +       name="Gloves"> +        <menu_item_call.on_click +         function="Edit.TakeOff" +         parameter="gloves" /> +        <menu_item_call.on_enable +         function="Edit.EnableTakeOff" +         parameter="gloves" /> +      </menu_item_call> +      <menu_item_call +            enabled="false" +            label="Undershirt" +            layout="topleft" +            name="Self Undershirt"> +        <menu_item_call.on_click +         function="Edit.TakeOff" +         parameter="undershirt" /> +        <menu_item_call.on_enable +         function="Edit.EnableTakeOff" +         parameter="undershirt" /> +      </menu_item_call> +      <menu_item_call +        enabled="false" +        label="Underpants" +        layout="topleft" +        name="Self Underpants"> +        <menu_item_call.on_click +         function="Edit.TakeOff" +         parameter="underpants" /> +        <menu_item_call.on_enable +         function="Edit.EnableTakeOff" +         parameter="underpants" /> +      </menu_item_call> +      <menu_item_call +        enabled="false" +        label="Tattoo" +        layout="topleft" +        name="Self Tattoo"> +        <menu_item_call.on_click +         function="Edit.TakeOff" +         parameter="tattoo" /> +        <menu_item_call.on_enable +         function="Edit.EnableTakeOff" +         parameter="tattoo" /> +      </menu_item_call> +      <menu_item_call +        enabled="false" +        label="Physics" +        layout="topleft" +        name="Self Physics"> +        <menu_item_call.on_click +         function="Edit.TakeOff" +         parameter="physics" /> +        <menu_item_call.on_enable +         function="Edit.EnableTakeOff" +         parameter="physics" /> +      </menu_item_call> +      <menu_item_call +        enabled="false" +        label="Alpha" +        layout="topleft" +        name="Self Alpha"> +        <menu_item_call.on_click +         function="Edit.TakeOff" +         parameter="alpha" /> +        <menu_item_call.on_enable +         function="Edit.EnableTakeOff" +         parameter="alpha" /> +      </menu_item_call> +      <menu_item_separator +       layout="topleft" /> +      <menu_item_call +       label="All Clothes" +       layout="topleft" +       name="All Clothes"> +        <menu_item_call.on_click +         function="Edit.TakeOff" +         parameter="all" /> +      </menu_item_call> +    </context_menu> +    <context_menu +     label="HUD" +     layout="topleft" +     name="Detach Self HUD" /> +    <context_menu +     label="Detach" +     layout="topleft" +     name="Detach Self" /> +    <menu_item_call +     label="Detach All" +     layout="topleft" +     name="Detach All"> +      <menu_item_call.on_click +       function="Self.RemoveAllAttachments" +       parameter="" /> +      <menu_item_call.on_enable +       function="Self.EnableRemoveAllAttachments" /> +    </menu_item_call> +  </context_menu> +  <menu_item_separator/>    <menu_item_call -    label="My Friends" +    label="Sit / stand"      layout="topleft" -    name="Friends..."> +    name="Sit stand">      <menu_item_call.on_click -     function="SideTray.PanelPeopleTab" -     parameter="friends_panel" /> +     function="Self.ToggleSitStand"/> +    <menu_item_call.on_enable +     function="Self.EnableSitStand" />    </menu_item_call>    <menu_item_call -   label="My Groups" -   layout="topleft" -   name="Groups..."> +     label="Fly / land" +     name="Fly land">      <menu_item_call.on_click -     function="SideTray.PanelPeopleTab" -     parameter="groups_panel" /> +     function="Agent.toggleFlying" /> +    <menu_item_call.on_enable +     function="Agent.enableFlyLand" />    </menu_item_call>    <menu_item_call -    label="My Profile" -    layout="topleft" -    name="Profile..."> +     label="Stop animations" +     name="Stop Animating My Avatar">      <menu_item_call.on_click -     function="ShowAgentProfile" -     parameter="agent" /> +     function="Tools.StopAllAnimations" /> +  </menu_item_call> +  <menu_item_separator/> +  <menu_item_call label="Reset skeleton" +       layout="topleft" +       name="Reset Skeleton"> +       <menu_item_call.on_click +        function="Avatar.ResetSkeleton" /> +  </menu_item_call> +  <menu_item_call label="Reset skeleton and animations" +       layout="topleft" +       name="Reset Skeleton And Animations"> +       <menu_item_call.on_click +        function="Avatar.ResetSkeletonAndAnimations" />    </menu_item_call>    <menu_item_call   label="Debug Textures" @@ -152,27 +311,27 @@ name="Edit Outfit">              <menu_item_call.on_visible               function="Advanced.EnableAppearanceToXML"/>      </menu_item_call> -  <menu_item_separator -  layout="topleft" /> -  <menu_item_call - enabled="false" - label="Drop" - layout="topleft" - name="Drop"> -    <menu_item_call.on_click -     function="Attachment.Drop" /> -    <menu_item_call.on_enable -     function="Attachment.EnableDrop" /> -  </menu_item_call> -  <menu_item_separator -       layout="topleft" />    <menu_item_call       enabled="false"       label="Block Particle Owner"       name="Mute Particle">      <menu_item_call.on_click       function="Particle.Mute" /> -    <menu_item_call.on_enable +    <menu_item_call.on_visible       function="EnableMuteParticle" />    </menu_item_call> + +  <menu_item_separator +   layout="topleft" /> +   +  <menu_item_call +   enabled="false" +   label="Drop item" +   layout="topleft" +   name="Drop"> +    <menu_item_call.on_click +     function="Attachment.Drop" /> +    <menu_item_call.on_enable +     function="Attachment.EnableDrop" /> +  </menu_item_call>  </context_menu> diff --git a/indra/newview/skins/default/xui/en/menu_avatar_other.xml b/indra/newview/skins/default/xui/en/menu_avatar_other.xml index f9fb847910..acbb9b860d 100644 --- a/indra/newview/skins/default/xui/en/menu_avatar_other.xml +++ b/indra/newview/skins/default/xui/en/menu_avatar_other.xml @@ -165,16 +165,13 @@        </menu_item_call>        </context_menu> -  <menu_item_separator  -    layout="topleft"  name="Impostor seperator"/> -    <menu_item_call       enabled="false"       label="Block Particle Owner"       name="Mute Particle">      <menu_item_call.on_click       function="Particle.Mute" /> -    <menu_item_call.on_enable +    <menu_item_call.on_visible       function="EnableMuteParticle" />    </menu_item_call>  </context_menu> diff --git a/indra/newview/skins/default/xui/en/menu_avatar_self.xml b/indra/newview/skins/default/xui/en/menu_avatar_self.xml index 9e181d0b6d..500b6fffc2 100644 --- a/indra/newview/skins/default/xui/en/menu_avatar_self.xml +++ b/indra/newview/skins/default/xui/en/menu_avatar_self.xml @@ -3,209 +3,16 @@   layout="topleft"   name="Self Pie">      <menu_item_call -     label="Sit Down" +     label="Now wearing..."       layout="topleft" -     name="Sit Down Here"> +     name="NowWearing">          <menu_item_call.on_click -         function="Self.SitDown" -         parameter="" /> +         function="NowWearing" />          <menu_item_call.on_enable -         function="Self.EnableSitDown" /> +         function="Edit.EnableCustomizeAvatar" />      </menu_item_call>      <menu_item_call -     label="Stand Up" -     layout="topleft" -     name="Stand Up"> -        <menu_item_call.on_click -         function="Self.StandUp" -         parameter="" /> -        <menu_item_call.on_enable -         function="Self.EnableStandUp" /> -    </menu_item_call> -    <context_menu -     label="Take Off" -     layout="topleft" -     name="Take Off >"> -        <context_menu -         label="Clothes" -         layout="topleft" -         name="Clothes >"> -            <menu_item_call -             enabled="false" -             label="Shirt" -             layout="topleft" -             name="Shirt"> -                <menu_item_call.on_click -                 function="Edit.TakeOff" -                 parameter="shirt" /> -                <menu_item_call.on_enable -                 function="Edit.EnableTakeOff" -                 parameter="shirt" /> -            </menu_item_call> -            <menu_item_call -             enabled="false" -             label="Pants" -             layout="topleft" -             name="Pants"> -                <menu_item_call.on_click -                 function="Edit.TakeOff" -                 parameter="pants" /> -                <menu_item_call.on_enable -                 function="Edit.EnableTakeOff" -                 parameter="pants" /> -            </menu_item_call> -            <menu_item_call -             enabled="false" -             label="Skirt" -             layout="topleft" -             name="Skirt"> -                <menu_item_call.on_click -                 function="Edit.TakeOff" -                 parameter="skirt" /> -                <menu_item_call.on_enable -                 function="Edit.EnableTakeOff" -                 parameter="skirt" /> -            </menu_item_call> -            <menu_item_call -             enabled="false" -             label="Shoes" -             layout="topleft" -             name="Shoes"> -                <menu_item_call.on_click -                 function="Edit.TakeOff" -                 parameter="shoes" /> -                <menu_item_call.on_enable -                 function="Edit.EnableTakeOff" -                 parameter="shoes" /> -            </menu_item_call> -            <menu_item_call -             enabled="false" -             label="Socks" -             layout="topleft" -             name="Socks"> -                <menu_item_call.on_click -                 function="Edit.TakeOff" -                 parameter="socks" /> -                <menu_item_call.on_enable -                 function="Edit.EnableTakeOff" -                 parameter="socks" /> -            </menu_item_call> -            <menu_item_call -             enabled="false" -             label="Jacket" -             layout="topleft" -             name="Jacket"> -                <menu_item_call.on_click -                 function="Edit.TakeOff" -                 parameter="jacket" /> -                <menu_item_call.on_enable -                 function="Edit.EnableTakeOff" -                 parameter="jacket" /> -            </menu_item_call> -            <menu_item_call -             enabled="false" -             label="Gloves" -             layout="topleft" -             name="Gloves"> -                <menu_item_call.on_click -                 function="Edit.TakeOff" -                 parameter="gloves" /> -                <menu_item_call.on_enable -                 function="Edit.EnableTakeOff" -                 parameter="gloves" /> -            </menu_item_call> -           <menu_item_call -                 enabled="false" -                 label="Undershirt" -                 layout="topleft" -                 name="Self Undershirt"> -                    <menu_item_call.on_click -                     function="Edit.TakeOff" -                     parameter="undershirt" /> -                    <menu_item_call.on_enable -                     function="Edit.EnableTakeOff" -                     parameter="undershirt" /> -                </menu_item_call> -               <menu_item_call -                 enabled="false" -                 label="Underpants" -                 layout="topleft" -                 name="Self Underpants"> -                    <menu_item_call.on_click -                     function="Edit.TakeOff" -                     parameter="underpants" /> -                    <menu_item_call.on_enable -                     function="Edit.EnableTakeOff" -                     parameter="underpants" /> -                </menu_item_call> -               <menu_item_call -                 enabled="false" -                 label="Tattoo" -                 layout="topleft" -                 name="Self Tattoo"> -                    <menu_item_call.on_click -                     function="Edit.TakeOff" -                     parameter="tattoo" /> -                    <menu_item_call.on_enable -                     function="Edit.EnableTakeOff" -                     parameter="tattoo" /> -                </menu_item_call> -               <menu_item_call -                 enabled="false" -                 label="Physics" -                 layout="topleft" -                 name="Self Physics"> -                    <menu_item_call.on_click -                     function="Edit.TakeOff" -                     parameter="physics" /> -                    <menu_item_call.on_enable -                     function="Edit.EnableTakeOff" -                     parameter="physics" /> -                </menu_item_call> -               <menu_item_call -                 enabled="false" -                 label="Alpha" -                 layout="topleft" -                 name="Self Alpha"> -                    <menu_item_call.on_click -                     function="Edit.TakeOff" -                     parameter="alpha" /> -                    <menu_item_call.on_enable -                     function="Edit.EnableTakeOff" -                     parameter="alpha" /> -                </menu_item_call> -                <menu_item_separator -                 layout="topleft" /> -                <menu_item_call -                 label="All Clothes" -                 layout="topleft" -                 name="All Clothes"> -                    <menu_item_call.on_click -                     function="Edit.TakeOff" -                     parameter="all" /> -                </menu_item_call> -        </context_menu> -        <context_menu -         label="HUD" -         layout="topleft" -         name="Object Detach HUD" /> -        <context_menu -         label="Detach" -         layout="topleft" -         name="Object Detach" /> -        <menu_item_call -         label="Detach All" -         layout="topleft" -         name="Detach All"> -            <menu_item_call.on_click -             function="Self.RemoveAllAttachments" -             parameter="" /> -            <menu_item_call.on_enable -             function="Self.EnableRemoveAllAttachments" /> -        </menu_item_call> -    </context_menu> -     <menu_item_call -     label="My Appearance" +     label="My Outfits..."       layout="topleft"       name="Chenge Outfit">          <menu_item_call.on_click @@ -213,66 +20,250 @@          <menu_item_call.on_enable           function="Edit.EnableCustomizeAvatar" />      </menu_item_call> -    <menu_item_call label="Edit My Outfit"  -    layout="topleft" -    name="Edit Outfit"> -       <menu_item_call.on_click -        function="EditOutfit" /> -       <menu_item_call.on_enable -        function="Edit.EnableCustomizeAvatar" /> +   <menu_item_call label="Hover height..." +     layout="topleft" +     name="Hover Height"> +     <menu_item_call.on_click +      function="HoverHeight" /> +     <menu_item_call.on_enable +      function="Edit.EnableHoverHeight" />     </menu_item_call> -    <menu_item_call label="Edit My Shape"  +   <menu_item_call label="Shape..."       layout="topleft" -    name="Edit My Shape"> +    name="Edit Shape">         <menu_item_call.on_click          function="EditShape" />         <menu_item_call.on_enable          function="Edit.EnableEditShape" />     </menu_item_call> -   <menu_item_call label="Hover Height" -     layout="topleft" -     name="Hover Height"> -     <menu_item_call.on_click -      function="HoverHeight" /> -     <menu_item_call.on_enable -      function="Edit.EnableHoverHeight" /> +   <menu_item_call +      label="Edit outfit parts..."  +      layout="topleft" +      name="Edit Outfit"> +       <menu_item_call.on_click +        function="EditOutfit" /> +       <menu_item_call.on_enable +        function="Edit.EnableCustomizeAvatar" />     </menu_item_call> -   <menu_item_call label="Reset Skeleton" +  <context_menu +    label="Take off" +    layout="topleft" +    name="Take Off >"> +    <context_menu +     label="Clothes" +     layout="topleft" +     name="Clothes >"> +      <menu_item_call +       enabled="false" +       label="Shirt" +       layout="topleft" +       name="Shirt"> +        <menu_item_call.on_click +         function="Edit.TakeOff" +         parameter="shirt" /> +        <menu_item_call.on_enable +         function="Edit.EnableTakeOff" +         parameter="shirt" /> +      </menu_item_call> +      <menu_item_call +       enabled="false" +       label="Pants" +       layout="topleft" +       name="Pants"> +        <menu_item_call.on_click +         function="Edit.TakeOff" +         parameter="pants" /> +        <menu_item_call.on_enable +         function="Edit.EnableTakeOff" +         parameter="pants" /> +      </menu_item_call> +      <menu_item_call +       enabled="false" +       label="Skirt" +       layout="topleft" +       name="Skirt"> +        <menu_item_call.on_click +         function="Edit.TakeOff" +         parameter="skirt" /> +        <menu_item_call.on_enable +         function="Edit.EnableTakeOff" +         parameter="skirt" /> +      </menu_item_call> +      <menu_item_call +       enabled="false" +       label="Shoes" +       layout="topleft" +       name="Shoes"> +        <menu_item_call.on_click +         function="Edit.TakeOff" +         parameter="shoes" /> +        <menu_item_call.on_enable +         function="Edit.EnableTakeOff" +         parameter="shoes" /> +      </menu_item_call> +      <menu_item_call +       enabled="false" +       label="Socks" +       layout="topleft" +       name="Socks"> +        <menu_item_call.on_click +         function="Edit.TakeOff" +         parameter="socks" /> +        <menu_item_call.on_enable +         function="Edit.EnableTakeOff" +         parameter="socks" /> +      </menu_item_call> +      <menu_item_call +       enabled="false" +       label="Jacket" +       layout="topleft" +       name="Jacket"> +        <menu_item_call.on_click +         function="Edit.TakeOff" +         parameter="jacket" /> +        <menu_item_call.on_enable +         function="Edit.EnableTakeOff" +         parameter="jacket" /> +      </menu_item_call> +      <menu_item_call +       enabled="false" +       label="Gloves" +       layout="topleft" +       name="Gloves"> +        <menu_item_call.on_click +         function="Edit.TakeOff" +         parameter="gloves" /> +        <menu_item_call.on_enable +         function="Edit.EnableTakeOff" +         parameter="gloves" /> +      </menu_item_call> +      <menu_item_call +            enabled="false" +            label="Undershirt" +            layout="topleft" +            name="Self Undershirt"> +        <menu_item_call.on_click +         function="Edit.TakeOff" +         parameter="undershirt" /> +        <menu_item_call.on_enable +         function="Edit.EnableTakeOff" +         parameter="undershirt" /> +      </menu_item_call> +      <menu_item_call +        enabled="false" +        label="Underpants" +        layout="topleft" +        name="Self Underpants"> +        <menu_item_call.on_click +         function="Edit.TakeOff" +         parameter="underpants" /> +        <menu_item_call.on_enable +         function="Edit.EnableTakeOff" +         parameter="underpants" /> +      </menu_item_call> +      <menu_item_call +        enabled="false" +        label="Tattoo" +        layout="topleft" +        name="Self Tattoo"> +        <menu_item_call.on_click +         function="Edit.TakeOff" +         parameter="tattoo" /> +        <menu_item_call.on_enable +         function="Edit.EnableTakeOff" +         parameter="tattoo" /> +      </menu_item_call> +      <menu_item_call +        enabled="false" +        label="Physics" +        layout="topleft" +        name="Self Physics"> +        <menu_item_call.on_click +         function="Edit.TakeOff" +         parameter="physics" /> +        <menu_item_call.on_enable +         function="Edit.EnableTakeOff" +         parameter="physics" /> +      </menu_item_call> +      <menu_item_call +        enabled="false" +        label="Alpha" +        layout="topleft" +        name="Self Alpha"> +        <menu_item_call.on_click +         function="Edit.TakeOff" +         parameter="alpha" /> +        <menu_item_call.on_enable +         function="Edit.EnableTakeOff" +         parameter="alpha" /> +      </menu_item_call> +      <menu_item_separator +       layout="topleft" /> +      <menu_item_call +       label="All Clothes" +       layout="topleft" +       name="All Clothes"> +        <menu_item_call.on_click +         function="Edit.TakeOff" +         parameter="all" /> +      </menu_item_call> +    </context_menu> +    <context_menu +     label="HUD" +     layout="topleft" +     name="Object Detach HUD" /> +    <context_menu +     label="Detach" +     layout="topleft" +     name="Object Detach" /> +    <menu_item_call +     label="Detach All" +     layout="topleft" +     name="Detach All"> +      <menu_item_call.on_click +       function="Self.RemoveAllAttachments" +       parameter="" /> +      <menu_item_call.on_enable +       function="Self.EnableRemoveAllAttachments" /> +    </menu_item_call> +  </context_menu> +  <menu_item_separator/> +  <menu_item_call +    label="Sit / stand" +    layout="topleft" +    name="Sit stand"> +      <menu_item_call.on_click +       function="Self.ToggleSitStand"/> +      <menu_item_call.on_enable +       function="Self.EnableSitStand" /> +  </menu_item_call> +  <menu_item_call +     label="Fly / land" +     name="Fly land"> +      <menu_item_call.on_click +       function="Agent.toggleFlying" /> +      <menu_item_call.on_enable +       function="Agent.enableFlyLand" /> +  </menu_item_call> +  <menu_item_call +     label="Stop animations" +     name="Stop Animating My Avatar"> +        <menu_item_call.on_click +         function="Tools.StopAllAnimations" /> +  </menu_item_call> +  <menu_item_separator/> +  <menu_item_call label="Reset skeleton"       layout="topleft"       name="Reset Skeleton">       <menu_item_call.on_click        function="Avatar.ResetSkeleton" /> -   </menu_item_call> -  <menu_item_call label="Reset Skeleton And Animations" +  </menu_item_call> +  <menu_item_call label="Reset skeleton and animations"         layout="topleft"         name="Reset Skeleton And Animations">         <menu_item_call.on_click          function="Avatar.ResetSkeletonAndAnimations" />    </menu_item_call> -   <menu_item_call -     label="My Friends" -     layout="topleft" -     name="Friends..."> -        <menu_item_call.on_click -         function="SideTray.PanelPeopleTab" -         parameter="friends_panel" /> -    </menu_item_call> -    <menu_item_call -     label="My Groups" -     layout="topleft" -     name="Groups..."> -        <menu_item_call.on_click -         function="SideTray.PanelPeopleTab" -         parameter="groups_panel" /> -    </menu_item_call> -   <menu_item_call -     label="My Profile" -     layout="topleft" -     name="Profile..."> -        <menu_item_call.on_click -         function="ShowAgentProfile" -         parameter="agent" /> -    </menu_item_call>      <menu_item_call  		 label="Debug Textures"           name="Debug..."> @@ -289,8 +280,6 @@              <menu_item_call.on_visible               function="Advanced.EnableAppearanceToXML"/>      </menu_item_call> -  <menu_item_separator -       layout="topleft" />    <menu_item_call       enabled="false"       label="Block Particle Owner" @@ -298,7 +287,7 @@      <menu_item_call.on_click       function="Particle.Mute" /> -    <menu_item_call.on_enable +    <menu_item_call.on_visible       function="EnableMuteParticle" />    </menu_item_call>  </context_menu> diff --git a/indra/newview/skins/default/xui/en/menu_favorites.xml b/indra/newview/skins/default/xui/en/menu_favorites.xml index be380e11e5..0eab7c451b 100644 --- a/indra/newview/skins/default/xui/en/menu_favorites.xml +++ b/indra/newview/skins/default/xui/en/menu_favorites.xml @@ -21,12 +21,12 @@           parameter="about" />      </menu_item_call>      <menu_item_call -     label="Copy SLurl" +     label="Move to Landmarks"       layout="topleft" -     name="Copy slurl"> +     name="Move to Landmarks">          <menu_item_call.on_click           function="Favorites.DoToSelected" -         parameter="copy_slurl" /> +         parameter="move_to_landmarks" />      </menu_item_call>      <menu_item_call       label="Show on Map" @@ -36,6 +36,25 @@           function="Favorites.DoToSelected"           parameter="show_on_map" />      </menu_item_call> +    <menu_item_call +     label="Copy SLurl" +     layout="topleft" +     name="Copy slurl"> +        <menu_item_call.on_click +         function="Favorites.DoToSelected" +         parameter="copy_slurl" /> +    </menu_item_call> +    <menu_item_call +     label="Create Pick" +     layout="topleft" +     name="create_pick"> +        <menu_item_call.on_click +         function="Favorites.DoToSelected" +         parameter="create_pick" /> +        <menu_item_call.on_enable +         function="Favorites.EnableSelected" +         parameter="create_pick" /> +    </menu_item_call>      <menu_item_separator       layout="topleft" /> @@ -59,10 +78,14 @@           function="Favorites.EnableSelected"           parameter="can_paste" />      </menu_item_call> - -    <menu_item_separator -     layout="topleft" /> - +    <menu_item_call +     label="Rename" +     layout="topleft" +     name="rename"> +        <menu_item_call.on_click +         function="Favorites.DoToSelected" +         parameter="rename" /> +    </menu_item_call>      <menu_item_call       label="Delete"       layout="topleft" diff --git a/indra/newview/skins/default/xui/en/menu_inventory.xml b/indra/newview/skins/default/xui/en/menu_inventory.xml index eda9739976..5a35bbf121 100644 --- a/indra/newview/skins/default/xui/en/menu_inventory.xml +++ b/indra/newview/skins/default/xui/en/menu_inventory.xml @@ -152,6 +152,14 @@           parameter="category" />      </menu_item_call>      <menu_item_call +     label="New Outfit" +     layout="topleft" +     name="New Outfit"> +        <menu_item_call.on_click +         function="Inventory.DoCreate" +         parameter="outfit" /> +    </menu_item_call> +    <menu_item_call       label="New Script"       layout="topleft"       name="New Script"> diff --git a/indra/newview/skins/default/xui/en/menu_inventory_search_visibility.xml b/indra/newview/skins/default/xui/en/menu_inventory_search_visibility.xml new file mode 100644 index 0000000000..46193f4a7a --- /dev/null +++ b/indra/newview/skins/default/xui/en/menu_inventory_search_visibility.xml @@ -0,0 +1,44 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<toggleable_menu + bottom="806" + layout="topleft" + left="0" + mouse_opaque="false" + name="menu_search_visibility" + visible="false"> +  <menu_item_check +   label="Search Trash" +   layout="topleft" +   name="search_trash"> +    <on_click +     function="Inventory.GearDefault.Custom.Action" +     parameter="toggle_search_trash" /> +    <on_check +     function="Inventory.GearDefault.Check" +     parameter="toggle_search_trash" /> +  </menu_item_check> +  <menu_item_check +   label="Search Library" +   layout="topleft" +   name="search_library"> +    <on_click +     function="Inventory.GearDefault.Custom.Action" +     parameter="toggle_search_library" /> +    <on_check +     function="Inventory.GearDefault.Check" +     parameter="toggle_search_library" /> +  </menu_item_check> +  <menu_item_separator +   layout="topleft" /> +  <menu_item_check +   label="Include links" +   layout="topleft" +   name="include_links"> +    <on_click +     function="Inventory.GearDefault.Custom.Action" +     parameter="include_links" /> +    <on_check +     function="Inventory.GearDefault.Check" +     parameter="include_links" />          +  </menu_item_check>     +</toggleable_menu> diff --git a/indra/newview/skins/default/xui/en/menu_land.xml b/indra/newview/skins/default/xui/en/menu_land.xml index 2ad5cbbe95..1ce0d65b3e 100644 --- a/indra/newview/skins/default/xui/en/menu_land.xml +++ b/indra/newview/skins/default/xui/en/menu_land.xml @@ -18,6 +18,8 @@      <menu_item_call       label="Sit Here"       name="Sit Here"> +        <menu_item_call.on_enable +         function="Land.CanSit" />          <menu_item_call.on_click           function="Land.Sit" />      </menu_item_call> diff --git a/indra/newview/skins/default/xui/en/menu_login.xml b/indra/newview/skins/default/xui/en/menu_login.xml index 07b3cc3bd8..96fac1c6e8 100644 --- a/indra/newview/skins/default/xui/en/menu_login.xml +++ b/indra/newview/skins/default/xui/en/menu_login.xml @@ -57,20 +57,13 @@       tear_off="true"       name="Help">          <menu_item_call -         label="How to..." +         label="Guidebook"           name="How To"           shortcut="F1">              <menu_item_call.on_click               function="Help.ToggleHowTo"               parameter="" />          </menu_item_call> -        <menu_item_call -           label="Quickstart" -           name="Quickstart"> -            <menu_item_call.on_click -            function="Advanced.ShowURL" -            parameter="http://community.secondlife.com/t5/English-Knowledge-Base/Second-Life-Quickstart/ta-p/1087919"/> -        </menu_item_call>  		<menu_item_separator/>          <menu_item_call               label="Knowledge Base" diff --git a/indra/newview/skins/default/xui/en/menu_picks.xml b/indra/newview/skins/default/xui/en/menu_picks.xml index ebb49c9004..a408e6136c 100644 --- a/indra/newview/skins/default/xui/en/menu_picks.xml +++ b/indra/newview/skins/default/xui/en/menu_picks.xml @@ -3,7 +3,17 @@   layout="topleft"   name="Picks">      <menu_item_call -     label="Info" +     label="Teleport" +     layout="topleft" +     name="pick_teleport"> +        <menu_item_call.on_click +         function="Pick.Teleport" /> +        <menu_item_call.on_enable +         function="Pick.Enable"  +         parameter="teleport" /> +    </menu_item_call> +    <menu_item_call +     label="View Pick"       layout="topleft"       name="pick_info">          <menu_item_call.on_click @@ -13,7 +23,7 @@           parameter="info" />      </menu_item_call>      <menu_item_call -     label="Edit" +     label="Edit Pick"       layout="topleft"       name="pick_edit"       visible="false"> @@ -24,17 +34,7 @@           parameter="edit" />      </menu_item_call>      <menu_item_call -     label="Teleport" -     layout="topleft" -     name="pick_teleport"> -        <menu_item_call.on_click -         function="Pick.Teleport" /> -        <menu_item_call.on_enable -         function="Pick.Enable"  -         parameter="teleport" /> -    </menu_item_call> -    <menu_item_call -     label="Map" +     label="Show on map"       layout="topleft"       name="pick_map">          <menu_item_call.on_click diff --git a/indra/newview/skins/default/xui/en/menu_place_add_button.xml b/indra/newview/skins/default/xui/en/menu_place_add_button.xml index e3a39a1242..ad49f7c3a8 100644 --- a/indra/newview/skins/default/xui/en/menu_place_add_button.xml +++ b/indra/newview/skins/default/xui/en/menu_place_add_button.xml @@ -1,27 +1,30 @@  <?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<menu +<toggleable_menu   layout="topleft"   left="0"   mouse_opaque="false" - name="menu_folder_gear" + name="menu_create"   visible="false">      <menu_item_call -     label="Add Folder" +     label="Landmark current location"       layout="topleft" -     name="add_folder"> +     name="add_landmark">          <on_click           function="Places.LandmarksGear.Add.Action" -         parameter="category" /> +         parameter="add_landmark_root" />          <on_enable           function="Places.LandmarksGear.Enable" -         parameter="category" /> +         parameter="add_landmark_root" />      </menu_item_call>      <menu_item_call -     label="Add Landmark" +     label="Create folder"       layout="topleft" -     name="add_landmark"> +     name="add_folder">          <on_click           function="Places.LandmarksGear.Add.Action" -         parameter="add_landmark" /> +         parameter="category_root" /> +        <on_enable +         function="Places.LandmarksGear.Enable" +         parameter="category_root" />      </menu_item_call> -</menu> +</toggleable_menu> diff --git a/indra/newview/skins/default/xui/en/menu_places_gear_folder.xml b/indra/newview/skins/default/xui/en/menu_places_gear_folder.xml index 1aeb166e01..e9ada52a8f 100644 --- a/indra/newview/skins/default/xui/en/menu_places_gear_folder.xml +++ b/indra/newview/skins/default/xui/en/menu_places_gear_folder.xml @@ -7,15 +7,18 @@   name="menu_folder_gear"   visible="false">      <menu_item_call -     label="Add Landmark" +     label="Landmark current location"       layout="topleft"       name="add_landmark">          <on_click           function="Places.LandmarksGear.Add.Action"           parameter="add_landmark" /> +        <on_enable +         function="Places.LandmarksGear.Enable" +         parameter="add_landmark" />      </menu_item_call>      <menu_item_call -     label="Add Folder" +     label="Create subfolder"       layout="topleft"       name="add_folder">          <on_click @@ -24,6 +27,9 @@          <on_enable           function="Places.LandmarksGear.Enable"           parameter="category" /> +        <on_visible +         function="Places.LandmarksGear.Enable" +         parameter="category" />      </menu_item_call>      <menu_item_call       label="Restore Item" @@ -120,37 +126,4 @@           function="Places.LandmarksGear.Enable"           parameter="collapse" />      </menu_item_call> -    <menu_item_call -     label="Expand all folders" -     layout="topleft" -     name="expand_all"> -        <on_click -         function="Places.LandmarksGear.Folding.Action" -         parameter="expand_all" /> -        <on_enable -         function="Places.LandmarksGear.Enable" -         parameter="expand_all" /> -    </menu_item_call> -    <menu_item_call -     label="Collapse all folders" -     layout="topleft" -     name="collapse_all"> -        <on_click -         function="Places.LandmarksGear.Folding.Action" -         parameter="collapse_all" /> -        <on_enable -         function="Places.LandmarksGear.Enable" -         parameter="collapse_all" /> -    </menu_item_call> -    <menu_item_check -     label="Sort by Date" -     layout="topleft" -     name="sort_by_date"> -        <on_check -         function="Places.LandmarksGear.Check" -         parameter="sort_by_date" /> -        <on_click -         function="Places.LandmarksGear.Folding.Action" -         parameter="sort_by_date" /> -    </menu_item_check>  </toggleable_menu> diff --git a/indra/newview/skins/default/xui/en/menu_places_gear_landmark.xml b/indra/newview/skins/default/xui/en/menu_places_gear_landmark.xml index ff5fdd3795..c89b498ddf 100644 --- a/indra/newview/skins/default/xui/en/menu_places_gear_landmark.xml +++ b/indra/newview/skins/default/xui/en/menu_places_gear_landmark.xml @@ -18,7 +18,18 @@           parameter="teleport" />      </menu_item_call>      <menu_item_call -     label="More Information" +     label="Share" +     layout="topleft" +     name="share"> +        <on_click +         function="Places.LandmarksGear.Custom.Action" +         parameter="share" /> +        <on_enable +         function="Places.LandmarksGear.Enable" +         parameter="share" /> +    </menu_item_call> +    <menu_item_call +     label="View/Edit Landmark"       layout="topleft"       name="more_info">          <on_click @@ -29,6 +40,28 @@           parameter="more_info" />      </menu_item_call>      <menu_item_call +       label="Move to Landmarks" +       layout="topleft" +       name="Move to Landmarks"> +      <menu_item_call.on_click +       function="Places.LandmarksGear.Custom.Action" +       parameter="move_to_landmarks" /> +      <menu_item_call.on_visible +       function="Places.LandmarksGear.Enable" +       parameter="move_to_landmarks" /> +    </menu_item_call> +    <menu_item_call +       label="Move to Favorites" +       layout="topleft" +       name="Move to Favorites"> +      <menu_item_call.on_click +       function="Places.LandmarksGear.Custom.Action" +       parameter="move_to_favorites" /> +      <menu_item_call.on_visible +       function="Places.LandmarksGear.Enable" +       parameter="move_to_favorites" /> +    </menu_item_call> +    <menu_item_call       label="Show on Map"       layout="topleft"       name="show_on_map"> @@ -39,26 +72,27 @@           function="Places.LandmarksGear.Enable"           parameter="show_on_map" />      </menu_item_call> -    <menu_item_separator -     layout="topleft" />      <menu_item_call -     label="Add Landmark" +     label="Copy SLurl"       layout="topleft" -     name="add_landmark"> +     name="copy_slurl">          <on_click -         function="Places.LandmarksGear.Add.Action" -         parameter="add_landmark" /> -    </menu_item_call> +         function="Places.LandmarksGear.CopyPaste.Action" +         parameter="copy_slurl" /> +        <on_enable +         function="Places.LandmarksGear.Enable" +         parameter="copy_slurl" /> +    </menu_item_call>       <menu_item_call -     label="Add Folder" +     label="Create Pick"       layout="topleft" -     name="add_folder"> +     name="create_pick">          <on_click -         function="Places.LandmarksGear.Add.Action" -         parameter="category" /> +         function="Places.LandmarksGear.Custom.Action" +         parameter="create_pick" />          <on_enable           function="Places.LandmarksGear.Enable" -         parameter="category" /> +         parameter="create_pick" />      </menu_item_call>      <menu_item_call       label="Restore Item" @@ -82,7 +116,7 @@           parameter="cut" />      </menu_item_call>      <menu_item_call -     label="Copy Landmark" +     label="Copy"       layout="topleft"       name="copy_landmark">          <on_click @@ -90,17 +124,6 @@           parameter="copy" />      </menu_item_call>      <menu_item_call -     label="Copy SLurl" -     layout="topleft" -     name="copy_slurl"> -        <on_click -         function="Places.LandmarksGear.CopyPaste.Action" -         parameter="copy_slurl" /> -        <on_enable -         function="Places.LandmarksGear.Enable" -         parameter="copy_slurl" /> -    </menu_item_call> -    <menu_item_call       label="Paste"       layout="topleft"       name="paste"> @@ -133,53 +156,4 @@           function="Places.LandmarksGear.Enable"           parameter="delete" />      </menu_item_call> -    <menu_item_separator -     layout="topleft" /> -    <menu_item_call -     label="Expand all folders" -     layout="topleft" -     name="expand_all"> -        <on_click -         function="Places.LandmarksGear.Folding.Action" -         parameter="expand_all" /> -        <on_enable -         function="Places.LandmarksGear.Enable" -         parameter="expand_all" /> -    </menu_item_call> -    <menu_item_call -     label="Collapse all folders" -     layout="topleft" -     name="collapse_all"> -        <on_click -         function="Places.LandmarksGear.Folding.Action" -         parameter="collapse_all" /> -        <on_enable -         function="Places.LandmarksGear.Enable" -         parameter="collapse_all" /> -    </menu_item_call> -    <menu_item_check -     label="Sort by Date" -     layout="topleft" -     name="sort_by_date"> -        <on_check -         function="Places.LandmarksGear.Check" -         parameter="sort_by_date" /> -        <on_click -         function="Places.LandmarksGear.Folding.Action" -         parameter="sort_by_date" /> -        <on_enable -         function="Places.LandmarksGear.Enable" -         parameter="sort_by_date" /> -    </menu_item_check> -    <menu_item_call -     label="Create Pick" -     layout="topleft" -     name="create_pick"> -        <on_click -         function="Places.LandmarksGear.Custom.Action" -         parameter="create_pick" /> -        <on_enable -         function="Places.LandmarksGear.Enable" -         parameter="create_pick" /> -    </menu_item_call>  </toggleable_menu> diff --git a/indra/newview/skins/default/xui/en/menu_places_gear_sorting.xml b/indra/newview/skins/default/xui/en/menu_places_gear_sorting.xml new file mode 100644 index 0000000000..4193a72e2e --- /dev/null +++ b/indra/newview/skins/default/xui/en/menu_places_gear_sorting.xml @@ -0,0 +1,46 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<toggleable_menu + layout="topleft" + left="0" + mouse_opaque="false" + name="menu_sorter_gear" + visible="false"> +    <menu_item_call +     label="Expand all folders" +     layout="topleft" +     name="expand_all"> +        <on_click +         function="Places.LandmarksGear.Folding.Action" +         parameter="expand_all" /> +        <on_enable +         function="Places.LandmarksGear.Enable" +         parameter="expand_all" /> +    </menu_item_call> +    <menu_item_call +     label="Collapse all folders" +     layout="topleft" +     name="collapse_all"> +        <on_click +         function="Places.LandmarksGear.Folding.Action" +         parameter="collapse_all" /> +        <on_enable +         function="Places.LandmarksGear.Enable" +         parameter="collapse_all" /> +    </menu_item_call> +    <menu_item_separator +     layout="topleft" /> +    <menu_item_check +     label="Sort by Date" +     layout="topleft" +     name="sort_by_date"> +        <on_check +         function="Places.LandmarksGear.Check" +         parameter="sort_by_date" /> +        <on_click +         function="Places.LandmarksGear.Folding.Action" +         parameter="sort_by_date" /> +        <on_enable +         function="Places.LandmarksGear.Enable" +         parameter="sort_by_date" /> +    </menu_item_check> +</toggleable_menu> diff --git a/indra/newview/skins/default/xui/en/menu_teleport_history_gear.xml b/indra/newview/skins/default/xui/en/menu_teleport_history_gear.xml index bc7d4fe33b..c11d668698 100644 --- a/indra/newview/skins/default/xui/en/menu_teleport_history_gear.xml +++ b/indra/newview/skins/default/xui/en/menu_teleport_history_gear.xml @@ -12,7 +12,8 @@       label="Expand all folders"       name="Expand all folders">          <menu_item_call.on_click -         function="TeleportHistory.ExpandAllFolders" /> +         function="TeleportHistory.GearMenu.Action" +         parameter="expand_all" />          <on_enable           function="TeleportHistory.GearMenu.Enable"           parameter="expand_all" /> @@ -21,16 +22,10 @@       label="Collapse all folders"       name="Collapse all folders">          <menu_item_call.on_click -         function="TeleportHistory.CollapseAllFolders" /> +         function="TeleportHistory.GearMenu.Action" +         parameter="collapse_all" />          <on_enable           function="TeleportHistory.GearMenu.Enable"           parameter="collapse_all" />      </menu_item_call> -    <menu_item_separator layout="topleft" /> -    <menu_item_call -     label="Clear Teleport History" -     name="Clear Teleport History"> -        <menu_item_call.on_click -         function="TeleportHistory.ClearTeleportHistory" /> -    </menu_item_call>      </toggleable_menu> diff --git a/indra/newview/skins/default/xui/en/menu_teleport_history_item.xml b/indra/newview/skins/default/xui/en/menu_teleport_history_item.xml index f939c3996d..153e5a70a9 100644 --- a/indra/newview/skins/default/xui/en/menu_teleport_history_item.xml +++ b/indra/newview/skins/default/xui/en/menu_teleport_history_item.xml @@ -1,26 +1,52 @@  <?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<context_menu +<toggleable_menu + name="Teleport History Item Menu"   layout="topleft" - name="Teleport History Item Context Menu"> + left="0" + mouse_opaque="false" + visible="false">      <menu_item_call       label="Teleport"       layout="topleft"       name="Teleport"> -        <menu_item_call.on_click -         function="TeleportHistory.Teleport" /> +        <on_click +         function="TeleportHistory.GearMenu.Action" +         parameter="teleport" /> +        <on_enable +         function="TeleportHistory.GearMenu.Enable" +         parameter="teleport" />      </menu_item_call>      <menu_item_call -     label="More Information" +     label="View"       layout="topleft"       name="More Information"> -        <menu_item_call.on_click -         function="TeleportHistory.MoreInformation" /> +        <on_click +         function="TeleportHistory.GearMenu.Action" +         parameter="view" /> +        <on_enable +         function="TeleportHistory.GearMenu.Enable" +         parameter="view" /> +    </menu_item_call> +    <menu_item_call +     label="Show on map" +     layout="topleft" +     name="show_on_map"> +        <on_click +         function="TeleportHistory.GearMenu.Action" +         parameter="show_on_map" /> +        <on_enable +         function="TeleportHistory.GearMenu.Enable" +         parameter="show_on_map" />      </menu_item_call>      <menu_item_call       label="Copy SLurl"       layout="topleft"       name="CopyToClipboard"> -        <menu_item_call.on_click -         function="TeleportHistory.CopyToClipboard" /> +        <on_click +         function="TeleportHistory.GearMenu.Action" +         parameter="copy_slurl" /> +        <on_enable +         function="TeleportHistory.GearMenu.Enable" +         parameter="copy_slurl" />      </menu_item_call> -</context_menu> +</toggleable_menu> diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index 9ff9966186..a06010f03f 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -15,24 +15,6 @@           function="ShowAgentProfile"           parameter="agent" />        </menu_item_call> -      <menu_item_call -       label="Appearance..." -       name="ChangeOutfit" -       shortcut="control|O"> -        <menu_item_call.on_click -         function="Floater.ToggleOrBringToFront" -         parameter="appearance" /> -        <menu_item_call.on_enable -         function="Edit.EnableCustomizeAvatar" /> -      </menu_item_call> -      <menu_item_call -       label="Choose an avatar..." -       name="Avatar Picker"> -        <menu_item_call.on_click -         function="Floater.ToggleOrBringToFront" -         parameter="avatar" /> -      </menu_item_call> -      <menu_item_separator/>        <menu_item_check           label="Inventory..."           name="Inventory" @@ -75,14 +57,6 @@            parameter="experiences"/>        </menu_item_call>        <menu_item_call -        label="My Scripts..." -        name="MyScripts"> -        <menu_item_call.on_click -          function="Floater.ToggleOrBringToFront" -          parameter="my_scripts"/> -      </menu_item_call> -      <menu_item_separator/> -      <menu_item_call         label="Camera Controls..."         name="Camera Controls"         shortcut="control|K"> @@ -90,119 +64,24 @@           function="Floater.ToggleOrBringToFront"           parameter="camera" />        </menu_item_call> -      <menu_item_call -       label="Hover Height" -       name="HoverHeight" -       shortcut="alt|control|H" -       use_mac_ctrl="true" -       visible="false"> -        <menu_item_call.on_click -         function="Floater.ToggleOrBringToFront" -         parameter="edit_hover_height"/> -        <menu_item_call.on_enable -         function="Edit.EnableHoverHeight"/> -      </menu_item_call> -      <menu -       create_jump_keys="true" -       label="Movement" -       name="Movement" -       tear_off="true"> -        <menu_item_call -         label="Sit Down" -         layout="topleft" -         shortcut="alt|shift|S" -         name="Sit Down Here"> -          <menu_item_call.on_click -           function="Self.SitDown"/> -          <menu_item_call.on_visible -           function="Self.ShowSitDown"/> -          <menu_item_call.on_enable -           function="Self.EnableSitDown" /> -        </menu_item_call> -        <menu_item_call -         label="Stand Up" -         layout="topleft" -         shortcut="alt|shift|S" -         name="Stand up"> -          <menu_item_call.on_click -           function="Self.StandUp"/> -          <menu_item_call.on_visible -           function="Self.EnableStandUp"/> -          <menu_item_call.on_enable -           function="Self.EnableStandUp" /> -        </menu_item_call> -        <menu_item_check -         label="Fly" -         name="Fly" -         shortcut="HOME"> -          <menu_item_check.on_check -           function="Agent.getFlying" /> -          <menu_item_check.on_click -           function="Agent.toggleFlying" /> -          <menu_item_check.on_enable -           function="Agent.enableFlying" /> -        </menu_item_check> -        <menu_item_call -         label="Stop flying" -         name="Stop flying" -         shortcut="HOME"> -          <menu_item_call.on_click -           function="Agent.toggleFlying" /> -          <menu_item_call.on_enable -           function="Agent.getFlying" /> -        </menu_item_call>	 -        <menu_item_check -         label="Always Run" -         name="Always Run" -         shortcut="control|R"> -          <menu_item_check.on_check -           function="World.CheckAlwaysRun" /> -          <menu_item_check.on_click -           function="World.AlwaysRun" /> -        </menu_item_check> -        <menu_item_call -         label="Stop Animating Me" -         name="Stop Animating My Avatar" -         allow_key_repeat="true" -         shortcut="alt|shift|A"> -          <menu_item_call.on_click -           function="Tools.StopAllAnimations" /> -        </menu_item_call> -        <menu_item_check -         label="Walk / run / fly..." -         name="WalkRunFly"> -          <menu_item_check.on_check -           function="Floater.Visible" -           parameter="moveview" /> -          <menu_item_check.on_click -           function="Floater.ToggleOrBringToFront" -           parameter="moveview" /> -        </menu_item_check> -      </menu> -      <menu -       create_jump_keys="true" -       label="Status" -       name="Status" -       tear_off="true"> -        <menu_item_check -         name="Away" -         label="Away"> -          <menu_item_check.on_check -           function="View.Status.CheckAway" /> -          <menu_item_check.on_click -           function="World.SetAway" /> -        </menu_item_check> -        <menu_item_check -         name="Do Not Disturb" -         label="Do Not Disturb"> -          <menu_item_check.on_check -           function="View.Status.CheckDoNotDisturb" /> -          <menu_item_check.on_click -           function="World.SetDoNotDisturb"/> -        </menu_item_check> -       -    </menu> +      <menu_item_separator/> +      <menu_item_check +       name="Away" +       label="Away"> +        <menu_item_check.on_check +         function="View.Status.CheckAway" /> +        <menu_item_check.on_click +         function="World.SetAway" /> +      </menu_item_check> +      <menu_item_check +       name="Do Not Disturb" +       label="Do Not Disturb"> +        <menu_item_check.on_check +         function="View.Status.CheckDoNotDisturb" /> +        <menu_item_check.on_click +         function="World.SetDoNotDisturb"/> +      </menu_item_check>        <menu_item_separator/> @@ -227,6 +106,15 @@           name="ManageMyAccount_url"           parameter="WebLaunchJoinNow,http://secondlife.com/account/" />        </menu_item_call> +      <menu_item_call +           label="[Membership]" +           name="Membership"> +            <menu_item_call.on_click +             function="Advanced.ShowURL" +             parameter="https://secondlife.com/my/account/membership.php"/> +            <menu_item_call.on_visible +                 function="Membership.UpdateLabel"/> +      </menu_item_call>        <menu_item_separator/> @@ -274,6 +162,334 @@      </menu>      <menu       create_jump_keys="true" +     label="Avatar" +     name="Avatar" +     tear_off="true"> +       <menu_item_call +         label="Now wearing..." +         name="NowWearing" +         shortcut="control|O"> +            <menu_item_call.on_click +             function="NowWearing" /> +            <menu_item_call.on_enable +             function="Edit.EnableCustomizeAvatar" /> +       </menu_item_call> +       <menu_item_call +         label="My outfits..." +         name="ChangeOutfit"> +            <menu_item_call.on_click +             function="CustomizeAvatar" /> +            <menu_item_call.on_enable +             function="Edit.EnableCustomizeAvatar" /> +       </menu_item_call> +       <menu_item_call label="Hover height..." +         layout="topleft" +         shortcut="alt|control|H" +         name="Hover Height"> +            <menu_item_call.on_click +             function="HoverHeight" /> +            <menu_item_call.on_enable +             function="Edit.EnableHoverHeight" /> +      </menu_item_call> +      <menu_item_call +        label="Edit shape..." +        layout="topleft" +        name="Edit My Shape"> +            <menu_item_call.on_click +             function="EditShape" /> +            <menu_item_call.on_enable +             function="Edit.EnableEditShape" /> +      </menu_item_call> +      <menu_item_call +        label="Edit outfit parts..." +        layout="topleft" +        name="Edit Outfit"> +            <menu_item_call.on_click +             function="EditOutfit" /> +            <menu_item_call.on_enable +             function="Edit.EnableCustomizeAvatar" /> +      </menu_item_call> +      <menu +        label="Take off" +        layout="topleft" +        name="Take Off >"> +        <menu +         label="Clothes" +         layout="topleft" +         name="Clothes >"> +          <menu_item_call +           enabled="false" +           label="Shirt" +           layout="topleft" +           name="Shirt"> +            <menu_item_call.on_click +             function="Edit.TakeOff" +             parameter="shirt" /> +            <menu_item_call.on_enable +             function="Edit.EnableTakeOff" +             parameter="shirt" /> +          </menu_item_call> +          <menu_item_call +           enabled="false" +           label="Pants" +           layout="topleft" +           name="Pants"> +            <menu_item_call.on_click +             function="Edit.TakeOff" +             parameter="pants" /> +            <menu_item_call.on_enable +             function="Edit.EnableTakeOff" +             parameter="pants" /> +          </menu_item_call> +          <menu_item_call +           enabled="false" +           label="Skirt" +           layout="topleft" +           name="Skirt"> +            <menu_item_call.on_click +             function="Edit.TakeOff" +             parameter="skirt" /> +            <menu_item_call.on_enable +             function="Edit.EnableTakeOff" +             parameter="skirt" /> +          </menu_item_call> +          <menu_item_call +           enabled="false" +           label="Shoes" +           layout="topleft" +           name="Shoes"> +            <menu_item_call.on_click +             function="Edit.TakeOff" +             parameter="shoes" /> +            <menu_item_call.on_enable +             function="Edit.EnableTakeOff" +             parameter="shoes" /> +          </menu_item_call> +          <menu_item_call +           enabled="false" +           label="Socks" +           layout="topleft" +           name="Socks"> +            <menu_item_call.on_click +             function="Edit.TakeOff" +             parameter="socks" /> +            <menu_item_call.on_enable +             function="Edit.EnableTakeOff" +             parameter="socks" /> +          </menu_item_call> +          <menu_item_call +           enabled="false" +           label="Jacket" +           layout="topleft" +           name="Jacket"> +            <menu_item_call.on_click +             function="Edit.TakeOff" +             parameter="jacket" /> +            <menu_item_call.on_enable +             function="Edit.EnableTakeOff" +             parameter="jacket" /> +          </menu_item_call> +          <menu_item_call +           enabled="false" +           label="Gloves" +           layout="topleft" +           name="Gloves"> +            <menu_item_call.on_click +             function="Edit.TakeOff" +             parameter="gloves" /> +            <menu_item_call.on_enable +             function="Edit.EnableTakeOff" +             parameter="gloves" /> +          </menu_item_call> +          <menu_item_call +                enabled="false" +                label="Undershirt" +                layout="topleft" +                name="Self Undershirt"> +            <menu_item_call.on_click +             function="Edit.TakeOff" +             parameter="undershirt" /> +            <menu_item_call.on_enable +             function="Edit.EnableTakeOff" +             parameter="undershirt" /> +          </menu_item_call> +          <menu_item_call +            enabled="false" +            label="Underpants" +            layout="topleft" +            name="Self Underpants"> +            <menu_item_call.on_click +             function="Edit.TakeOff" +             parameter="underpants" /> +            <menu_item_call.on_enable +             function="Edit.EnableTakeOff" +             parameter="underpants" /> +          </menu_item_call> +          <menu_item_call +            enabled="false" +            label="Tattoo" +            layout="topleft" +            name="Self Tattoo"> +            <menu_item_call.on_click +             function="Edit.TakeOff" +             parameter="tattoo" /> +            <menu_item_call.on_enable +             function="Edit.EnableTakeOff" +             parameter="tattoo" /> +          </menu_item_call> +          <menu_item_call +            enabled="false" +            label="Physics" +            layout="topleft" +            name="Self Physics"> +            <menu_item_call.on_click +             function="Edit.TakeOff" +             parameter="physics" /> +            <menu_item_call.on_enable +             function="Edit.EnableTakeOff" +             parameter="physics" /> +          </menu_item_call> +          <menu_item_call +            enabled="false" +            label="Alpha" +            layout="topleft" +            name="Self Alpha"> +            <menu_item_call.on_click +             function="Edit.TakeOff" +             parameter="alpha" /> +            <menu_item_call.on_enable +             function="Edit.EnableTakeOff" +             parameter="alpha" /> +          </menu_item_call> +          <menu_item_separator +           layout="topleft" /> +          <menu_item_call +           label="All Clothes" +           layout="topleft" +           name="All Clothes"> +            <menu_item_call.on_click +             function="Edit.TakeOff" +             parameter="all" /> +          </menu_item_call> +        </menu> +        <menu +         label="HUD" +         layout="topleft" +         name="Avatar Detach HUD" /> +        <menu +         label="Detach" +         layout="topleft" +         name="Avatar Detach" /> +        <menu_item_call +         label="Detach All" +         layout="topleft" +         name="Detach All"> +          <menu_item_call.on_click +           function="Self.RemoveAllAttachments" +           parameter="" /> +          <menu_item_call.on_enable +           function="Self.EnableRemoveAllAttachments" /> +        </menu_item_call> +      </menu> +      <menu_item_separator/> +      <menu_item_call +        label="Complete avatars..." +        name="Avatar Picker"> +        <menu_item_call.on_click +         function="Floater.ToggleOrBringToFront" +         parameter="avatar" /> +      </menu_item_call> +      <menu_item_separator/> + +      <menu_item_call +         label="Sit / stand" +         layout="topleft" +         shortcut="alt|shift|S" +         name="Sit stand"> +          <menu_item_call.on_click +           function="Self.ToggleSitStand"/> +          <menu_item_call.on_enable +           function="Self.EnableSitStand" /> +        </menu_item_call> +        <menu_item_call +         label="Fly / land" +         name="Fly land" +         shortcut="HOME"> +          <menu_item_call.on_click +           function="Agent.toggleFlying" /> +          <menu_item_call.on_enable +           function="Agent.enableFlyLand" /> +        </menu_item_call>        +        <menu_item_call +         label="Stop animations" +         name="Stop Animating My Avatar"> +          <menu_item_call.on_click +           function="Tools.StopAllAnimations" /> +        </menu_item_call> +        <menu_item_check +          label="Walk / run / fly..." +          name="WalkRunFly"> +          <menu_item_check.on_check +           function="Floater.Visible" +           parameter="moveview" /> +          <menu_item_check.on_click +           function="Floater.ToggleOrBringToFront" +           parameter="moveview" /> +        </menu_item_check> +        <menu_item_check +          label="Always run" +          name="Always Run" +          shortcut="control|R"> +          <menu_item_check.on_check +           function="World.CheckAlwaysRun" /> +          <menu_item_check.on_click +           function="World.AlwaysRun" /> +        </menu_item_check> +      <menu_item_separator/> +      <menu_item_check +       label="Gestures..." +       name="Gestures" +       shortcut="control|G"> +        <menu_item_check.on_check +         function="Floater.Visible" +         parameter="gestures" /> +        <menu_item_check.on_click +         function="Floater.Toggle" +         parameter="gestures" /> +      </menu_item_check> +      <menu_item_separator/> +      <menu_item_call  +       label="Reset skeleton" +       layout="topleft" +       name="Reset Skeleton"> +        <menu_item_call.on_click +         function="Avatar.ResetSkeleton" /> +      </menu_item_call> +      <menu_item_call  +       label="Reset skeleton and animations" +       layout="topleft" +       name="Reset Skeleton And Animations"> +        <menu_item_call.on_click +         function="Avatar.ResetSkeletonAndAnimations" /> +      </menu_item_call> +      <menu_item_call +       label="Attachment scripts..." +       name="MyScripts"> +        <menu_item_call.on_click +         function="Floater.ToggleOrBringToFront" +         parameter="my_scripts"/> +      </menu_item_call> +      <menu_item_separator/> +      <menu_item_call +     label="Help with avatars..." +     name="Help with avatars"> +        <menu_item_call.on_click +            function="Advanced.ShowURL" +            parameter="https://community.secondlife.com/search/?type=cms_records3&tags=avatar&nodes=30&search_and_or=or"/> +      </menu_item_call> +    </menu> +    <menu +     create_jump_keys="true"       label="Communicate"       name="Communicate"       tear_off="true"> @@ -539,12 +755,18 @@               parameter="region_info" />          </menu_item_call>          <menu_item_call -         label="My land holdings..." -         name="My Land"> +         label="My Linden Home..." +         name="Linden Home"> +            <menu_item_call.on_click +             function="World.LindenHome"/> +        </menu_item_call> +        <menu_item_call +             label="My land holdings..." +             name="My Land">              <menu_item_call.on_click               function="Floater.Show"               parameter="land_holdings" /> -        </menu_item_call> +      </menu_item_call>          <menu_item_call           label="Buy this land"           name="Buy Land"> @@ -1387,20 +1609,13 @@ function="World.EnvPreset"       name="Help"       tear_off="true">          <menu_item_call -         label="How to..." +         label="Guidebook"           name="How To"           shortcut="F1">              <menu_item_call.on_click               function="Help.ToggleHowTo"               parameter="" />          </menu_item_call> -        <menu_item_call -           label="Quickstart" -           name="Quickstart"> -            <menu_item_call.on_click -            function="Advanced.ShowURL" -            parameter="http://community.secondlife.com/t5/English-Knowledge-Base/Second-Life-Quickstart/ta-p/1087919"/> -        </menu_item_call>  <!--        <menu_item_call           label="Tutorial"           name="Tutorial"> @@ -2441,6 +2656,18 @@ function="World.EnvPreset"                   function="Advanced.ForceErrorSoftwareException" />              </menu_item_call>              <menu_item_call +             label="Force a Crash in a Coroutine" +             name="Force a Crash in a Coroutine"> +                <menu_item_call.on_click +                 function="Advanced.ForceErrorCoroutineCrash" /> +            </menu_item_call> +            <menu_item_call +             label="Force a Crash in a Thread" +             name="Force a Crash in a Thread"> +                <menu_item_call.on_click +                 function="Advanced.ForceErrorThreadCrash" /> +            </menu_item_call> +            <menu_item_call               label="Force Disconnect Viewer"               name="Force Disconnect Viewer">                  <menu_item_call.on_click diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index cc0dc5c3cc..d4f71fb370 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -1024,18 +1024,6 @@ The group no longer has open enrollment.    <notification     icon="alertmodal.tga" -   name="JoinGroupSuccess" -   type="alertmodal"> -You have been added to the group -    <tag>group_id</tag> -    <tag>success</tag> -    <usetemplate -       name="okbutton" -       yestext="OK"/> -  </notification> -   -  <notification -   icon="alertmodal.tga"     name="JoinGroupInsufficientFunds"     type="alertmodal">  Unable to transfer the required L$ [membership_fee] membership fee. @@ -2332,6 +2320,29 @@ You cannot create a landmark here because the owner of the land doesn't all    </notification>    <notification + icon="alertmodal.tga" + label="Create folder" + name="CreateLandmarkFolder" + type="alertmodal"> +    <unique/> +    Choose a name for the folder: +    <tag>confirm</tag> +    <form name="form"> +      <input name="message" type="text"> +      </input> +      <button +       default="true" +       index="0" +       name="OK" +       text="OK"/> +      <button +       index="1" +       name="Cancel" +       text="Cancel"/> +    </form> +  </notification> + +  <notification     icon="alertmodal.tga"     name="CannotRecompileSelectObjectsNoScripts"     type="alertmodal"> @@ -2443,9 +2454,8 @@ Teleport failed.     icon="alertmodal.tga"     name="invalid_tport"     type="alertmodal"> -Problem encountered processing your teleport request. You may need to log back in before you can teleport. -If you continue to get this message, please check the [SUPPORT_SITE]. -  <tag>fail</tag> +Teleport attempts are limited to 6 per minute. If you are having trouble, wait one minute and try teleporting again. If the problem persists, log out and log in again. +    <tag>fail</tag>    </notification>    <notification     icon="alertmodal.tga" @@ -3153,7 +3163,30 @@ See https://wiki.secondlife.com/wiki/Adding_Spelling_Dictionaries         text="Cancel"/>      </form>    </notification> -   + +  <notification +   icon="alertmodal.tga" +   label="Rename Landmark" +   name="RenameLandmark" +   type="alertmodal"> +    Choose a new name for [NAME] +    <tag>confirm</tag> +    <form name="form"> +      <input name="new_name" type="text" width="300"> +        [NAME] +      </input> +      <button +       default="true" +       index="0" +       name="OK" +       text="OK"/> +      <button +       index="1" +       name="Cancel" +       text="Cancel"/> +    </form> +  </notification> +    <notification     icon="alertmodal.tga"     name="RemoveFromFriends" @@ -4257,13 +4290,6 @@ Leave Group?       yestext="OK"/>    </notification> -  <notification -   icon="notify.tga" -   name="GroupDepart" -   type="notify"> -You have left the group '<nolink>[group_name]</nolink>'. -    <tag>group</tag> -  </notification>    <notification     icon="alertmodal.tga" @@ -5066,7 +5092,9 @@ Do you wish to proceed?     name="RegionEntryAccessBlocked"     type="alertmodal">     <tag>fail</tag> -    The region you're trying to visit contains content exceeding your current preferences.  You can change your preferences using Me > Preferences > General. +    The region you’re trying to visit has a maturity rating exceeding your maximum maturity preference. Change this preference using Me menu > Preferences > General. + +Complete information on maturity ratings can be found [https://community.secondlife.com/knowledgebase/english/maturity-ratings-r52/ here].      <usetemplate       name="okbutton"       yestext="OK"/> @@ -5153,7 +5181,9 @@ The region you're trying to visit contains [REGIONMATURITY] content, but your cu     name="TeleportEntryAccessBlocked"     type="alertmodal">      <tag>fail</tag> -    The region you're trying to visit contains content exceeding your current preferences.  You can change your preferences using Me > Preferences > General. +    The region you’re trying to visit has a maturity rating exceeding your maximum maturity preference. Change this preference using Me menu > Preferences > General. + +Complete information on maturity ratings can be found [https://community.secondlife.com/knowledgebase/english/maturity-ratings-r52/ here].      <usetemplate       name="okbutton"       yestext="OK"/> @@ -5302,6 +5332,8 @@ You won't receive any more notifications that you're about to visit a region wit     name="LandClaimAccessBlocked"     type="alertmodal">      The land you're trying to claim has a maturity rating exceeding your current preferences.  You can change your preferences using Me > Preferences > General. + +Complete information on maturity ratings can be found [https://community.secondlife.com/knowledgebase/english/maturity-ratings-r52/ here].      <tag>fail</tag>      <usetemplate       name="okbutton" @@ -5371,6 +5403,8 @@ You won't receive any more notifications that you're about to visit a region wit     name="LandBuyAccessBlocked"     type="alertmodal">      The land you're trying to buy has a maturity rating exceeding your current preferences.  You can change your preferences using Me > Preferences > General. + +Complete information on maturity ratings can be found [https://community.secondlife.com/knowledgebase/english/maturity-ratings-r52/ here].      <tag>fail</tag>      <usetemplate       name="okbutton" @@ -7239,8 +7273,10 @@ You can only claim public land in the Region you're in.     name="RegionTPAccessBlocked"     type="alertmodal">     <tag>fail</tag> -    The region you're trying to visit contains content exceeding your current preferences.  You can change your preferences using Me > Preferences > General. -   <usetemplate +    The region you’re trying to visit has a maturity rating exceeding your maximum maturity preference. Change this preference using Me menu > Preferences > General. + +Complete information on maturity ratings can be found [https://community.secondlife.com/knowledgebase/english/maturity-ratings-r52/ here]. +    <usetemplate        name="okbutton"        yestext="OK"/>    </notification> @@ -8682,7 +8718,7 @@ This upload will cost L$[PRICE], do you wish to continue with the upload?     icon="alertmodal.tga"     name="ConfirmClearTeleportHistory"     type="alertmodal"> -Are you sure you want to delete your teleport history? +This will delete the entire list of places you have visited, and cannot be undone. Continue?    <tag>confirm</tag>      <usetemplate       name="okcancelbuttons" @@ -10019,6 +10055,15 @@ Removal of the object <nolink>'[OBJ_NAME]'</nolink> from the simulat  Cannot save your selection because you do not have permission to modify the object <nolink>'[OBJ_NAME]'</nolink>.    </notification> + +  <notification +   icon="alertmodal.tga" +   name="NoTransNoSaveToContents" +   type="notify"> +    <tag>fail</tag> +    Cannot save <nolink>'[OBJ_NAME]'</nolink> to object contents because you do not have permission to transfer the object's ownership. +  </notification> +    <notification     icon="alertmodal.tga"     name="NoCopyNoSaveSelection" @@ -11513,7 +11558,28 @@ Cannot create large prims that intersect other residents.  Please re-try when ot       name="okbutton"       yestext="OK"/>    </notification> -   + +  <notification +   icon="alertmodal.tga" +   name="AddPaymentMethod" +   type="alertmodal"> +On the following page, choose a L$ amount +and click a place Order button. You will be +able to add a payment method at checkout. +    <tag>confirm</tag> +    <form name="form"> +      <button +       default="true" +       index="0" +       width="120" +       name="Continue" +       text="Continue"/> +      <button +       index="1" +       name="Cancel" +       text="Cancel"/> +    </form> +  </notification>    <notification     icon="alert.tga" diff --git a/indra/newview/skins/default/xui/en/panel_edit_pick.xml b/indra/newview/skins/default/xui/en/panel_edit_pick.xml index 553c112e6f..357a5559bf 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_pick.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_pick.xml @@ -26,7 +26,7 @@       name="back_btn"       left="10"       tab_stop="false" -     top="2" +     top="4"       width="30"       use_draw_context_alpha="false" />     <text @@ -39,17 +39,17 @@       left_pad="4"       name="title"       text_color="LtGray" -     top="2" +     top="4"       width="250">          Edit Pick      </text>     <scroll_container       color="DkGray2"       follows="all" -     height="502" +     height="501"       layout="topleft"       left="8" -     top_pad="10" +     top_pad="9"       name="profile_scroll"       opaque="true"       width="312"> diff --git a/indra/newview/skins/default/xui/en/panel_edit_wearable.xml b/indra/newview/skins/default/xui/en/panel_edit_wearable.xml index dc1553e6a3..85d73ece48 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_wearable.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_wearable.xml @@ -13,7 +13,7 @@   width="333">      <string       name="edit_shape_title"> -        Editing Shape +        Shape      </string>      <string       name="edit_skin_title"> diff --git a/indra/newview/skins/default/xui/en/panel_favorites.xml b/indra/newview/skins/default/xui/en/panel_favorites.xml new file mode 100644 index 0000000000..1e8ea34ad2 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_favorites.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel +   name="Favorites" +   layout="topleft"  +   left="0" +   border="false" +   background_visible="true" +   bg_alpha_color="DkGray" +   follows="all"> +    <places_inventory_panel +      allow_multi_select="true" +      border="false" +      top="1" +      left="3" +      bottom="0" +      follows="all" +      right="-3" +      mouse_opaque="true" +      name="favorites_list" +      folder_view.use_ellipses="true" +      start_folder.name="Favorites"/>         +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_landmark_info.xml b/indra/newview/skins/default/xui/en/panel_landmark_info.xml index 7935d66aee..e82305ef17 100644 --- a/indra/newview/skins/default/xui/en/panel_landmark_info.xml +++ b/indra/newview/skins/default/xui/en/panel_landmark_info.xml @@ -67,7 +67,7 @@       name="back_btn"       tool_tip="Back"       tab_stop="false" -     top="4" +     top="2"       width="30"       use_draw_context_alpha="false" />      <text @@ -78,20 +78,20 @@       left_pad="7"       name="title"       text_color="LtGray" -     top="3" +     top="2"       use_ellipses="true"       value="Place Profile"       width="280" />      <scroll_container       color="DkGray2"       follows="all" -     height="532" +     height="534"       layout="topleft"       left="9"       name="place_scroll"       opaque="true" -     top_pad="10" -     width="310"> +     top_pad="9" +     width="324">          <panel           bg_alpha_color="DkGray2"           follows="left|top|right" @@ -282,7 +282,6 @@                   enabled="false"                   use_bg_color="true"                   bg_color="DkGray0" -                 parse_urls="false"                   follows="left|top|right"                   height="22"                   layout="topleft" @@ -290,8 +289,18 @@                   name="title_value"                   text_color="white"                   top_pad="5" -                 use_ellipses="true" -                 width="290" />  +                 width="200" />  +                <button +                 follows="top|right" +                 height="24" +                 label="Edit" +                 layout="topleft" +                 left_pad="8" +                 mouse_opaque="false" +                 name="edit_btn" +                 tool_tip="Edit landmark information" +                 top_delta="-1" +                 width="83" />                  <line_editor                   follows="left|top|right"                   height="22" @@ -301,8 +310,8 @@                   name="title_editor"                   prevalidate_callback="ascii"                   text_readonly_color="white" -                 top_delta="0" -                 width="290" /> +                 top_delta="1" +                 width="290"/>                  <text                   follows="left|top"                   height="15" @@ -344,17 +353,6 @@                   name="folder_combo"                   top_pad="5"                   width="200" /> -                <button -                 follows="bottom|left|right" -                 height="23" -                 label="Edit" -                 layout="topleft" -                 left="0" -                 mouse_opaque="false" -                 name="edit_btn" -                 tool_tip="Edit landmark information" -                 top_pad="-42" -                 width="100" />              </panel>          </panel>      </scroll_container> diff --git a/indra/newview/skins/default/xui/en/panel_landmarks.xml b/indra/newview/skins/default/xui/en/panel_landmarks.xml index 67a09949ce..10b925ec93 100644 --- a/indra/newview/skins/default/xui/en/panel_landmarks.xml +++ b/indra/newview/skins/default/xui/en/panel_landmarks.xml @@ -1,198 +1,23 @@  <?xml version="1.0" encoding="utf-8" standalone="yes" ?>  <panel     name="Landmarks" -   top="0" -   height="400"     layout="topleft"      left="0" -   width="313"     help_topic="panel_landmarks"     border="false"     background_visible="true"     bg_alpha_color="DkGray"     follows="all"> -    <accordion -     background_visible="true" -     bg_alpha_color="DkGray2" -     bg_opaque_color="DkGray2" -     follows="all" -     height="373" -     layout="topleft" -     left="3" -     name="landmarks_accordion" -     top="0" -     width="307"> -        <accordion_tab -         layout="topleft" -         name="tab_favorites" -         title="Favorites bar"> -            <places_inventory_panel -             allow_multi_select="true" -             border="false" -             bottom="0" -             follows="all" -             height="126" -             left="0" -             mouse_opaque="true" -             name="favorites_list" -             scroll.hide_scrollbar="true" -             folder_view.use_ellipses="true" -             start_folder.name="Favorites" -             width="307"/> -        </accordion_tab> -        <accordion_tab -         layout="topleft" -         name="tab_landmarks" -         title="My Landmarks"> -            <places_inventory_panel -             allow_multi_select="true" -             border="false" -             bottom="0" -             follows="all" -             height="126" -             left="0" -             mouse_opaque="true" -             name="landmarks_list" -             scroll.hide_scrollbar="true" -             folder_view.use_ellipses="true" -             start_folder.name="Landmarks" -             width="307"/> -        </accordion_tab> -        <accordion_tab -         layout="topleft" -         name="tab_inventory" -         title="My Inventory"> -            <places_inventory_panel -             allow_multi_select="true" -             border="false" -             bottom="0" -             follows="all" -             height="126" -             left="0" -             mouse_opaque="true" -             name="my_inventory_list" -             scroll.hide_scrollbar="true" -             folder_view.use_ellipses="true" -             start_folder.name="My Inventory" -             width="307"/> -          </accordion_tab> -          <accordion_tab -           layout="topleft" -           name="tab_library" -           title="Library"> -            <places_inventory_panel -             allow_multi_select="true" -             border="false" -             bottom="0" -             follows="all" -             height="126" -             left="0" -             mouse_opaque="true" -             name="library_list" -             scroll.hide_scrollbar="true" -             folder_view.use_ellipses="true" -             start_folder.name="LIBRARY" -             width="313"/> -        </accordion_tab> -    </accordion> -    <panel -       background_visible="true" -     bevel_style="none" -     bottom="0" -     follows="left|right|bottom" -     height="27" -     layout="bottomleft" -     left="3" -     name="bottom_panel" -     width="313"> -     	 -     	  <layout_stack -		   animate="false" -		   border_size="0" -		   follows="left|right|bottom" -		   height="25" -		   layout="topleft" -		   orientation="horizontal" -		   top_pad="1" -		   left="0" -		   name="bottom_panel" -		   width="307"> -		      <layout_panel -		       auto_resize="false" -		       height="25" -		       layout="topleft" -		       name="options_gear_btn_panel" -		       width="32"> -		          <menu_button -		           follows="bottom|left" -		           tool_tip="Show additional options" -		           height="25" -		           image_hover_unselected="Toolbar_Left_Over" -		           image_overlay="OptionsMenu_Off" -		           image_selected="Toolbar_Left_Selected" -		           image_unselected="Toolbar_Left_Off" -		           layout="topleft" -		           left="0" -		           name="options_gear_btn" -		           top="0" -		           width="31" /> -		      </layout_panel> -		      <layout_panel -		       auto_resize="false" -		       height="25" -		       layout="topleft" -		       name="add_btn_panel" -		       width="32"> -		          <button -		           follows="bottom|left" -		           height="25" -		           image_hover_unselected="Toolbar_Middle_Over" -		           image_overlay="AddItem_Off" -		           image_selected="Toolbar_Middle_Selected" -		           image_unselected="Toolbar_Middle_Off" -		           layout="topleft" -		           left="0" -		           name="add_btn" -		           tool_tip="Add new landmark" -		           top="0" -		           width="31" /> -		      </layout_panel> -		      <layout_panel -		       auto_resize="true" -		       height="25" -		       layout="topleft" -		       name="dummy_panel" -		       width="212"> -		          <icon -		           follows="bottom|left|right" -		           height="25" -		           image_name="Toolbar_Middle_Off" -		           layout="topleft" -		           left="0" -		           top="0" -		           name="dummy_icon" -		           width="211" /> -		      </layout_panel> -		      <layout_panel -		       auto_resize="false" -		       height="25" -		       layout="topleft" -		       name="trash_btn_panel" -		       width="31"> -		          <dnd_button -		           follows="bottom|left" -		           height="25" -		           image_hover_unselected="Toolbar_Right_Over" -		           image_overlay="TrashItem_Off" -		           image_selected="Toolbar_Right_Selected" -		           image_unselected="Toolbar_Right_Off" -		           left="0" -		           layout="topleft" -		           name="trash_btn" -		           tool_tip="Remove selected landmark" -		           top="0" -		           width="31"/> -		      </layout_panel> -  	</layout_stack> -   </panel> +    <places_inventory_panel +      allow_multi_select="true" +      border="false" +      top="1" +      follows="all" +      left="3" +      bottom="0" +      right="-3" +      mouse_opaque="true" +      name="landmarks_list" +      folder_view.use_ellipses="true" +      start_folder.name="Landmarks"/>  </panel> diff --git a/indra/newview/skins/default/xui/en/panel_login_first.xml b/indra/newview/skins/default/xui/en/panel_login_first.xml index 726e713595..5568ccb792 100644 --- a/indra/newview/skins/default/xui/en/panel_login_first.xml +++ b/indra/newview/skins/default/xui/en/panel_login_first.xml @@ -234,32 +234,6 @@              left_pad="32"              name="image_right"              top="0" /> -          <text -            follows="left|top" -            font="SansSerifLarge" -            text_color="White" -            height="64" -            name="image_caption_left" -            left="0" -            halign="center" -            top="408" -            word_wrap="true" -            width="400"> -            Your first step is Learning Island. Find the exit portal! -          </text> -          <text -            follows="left|top" -            font="SansSerifLarge" -            text_color="White" -            height="64" -            name="image_caption_right" -            left="432" -            halign="center" -            top="408" -            word_wrap="true" -            width="400"> -            Then explore Social Island and meet other new residents! -          </text>          </layout_panel>          <layout_panel            height="100" diff --git a/indra/newview/skins/default/xui/en/panel_main_inventory.xml b/indra/newview/skins/default/xui/en/panel_main_inventory.xml index d77fbdec0a..2ff58035ed 100644 --- a/indra/newview/skins/default/xui/en/panel_main_inventory.xml +++ b/indra/newview/skins/default/xui/en/panel_main_inventory.xml @@ -32,30 +32,20 @@      		 left="12"  		     name="ItemcountText"  		     font="SansSerifMedium" -		     text_color="EmphasisColor" +		     text_color="InventoryItemLinkColor"  		     use_ellipses="true"  		     top_pad="0"  		     width="300">      Items:    </text> -  <filter_editor -   text_pad_left="10" -   follows="left|top|right" +  <combo_box     height="23" -   label="Enter search text"     layout="topleft"     left="10" -   max_length_chars="300" -   name="inventory search editor"     top="18" -   width="208" /> -  <combo_box -   height="23" -   layout="topleft" -   left_pad="4"     name="search_type" -   follows="top|right" -   width="90"> +   follows="top|left" +   width="88">      <item       label="Name"       name="Name" @@ -72,7 +62,27 @@       label="UUID"       name="UUID"       value="search_by_UUID"/> -    </combo_box> +  </combo_box> +  <menu_button +   follows="top|left" +   tool_tip="Show search visibility options" +   height="23" +   image_overlay="Inv_Toolbar_SearchVisibility" +   layout="topleft" +   left_pad="3" +   name="options_visibility_btn" +   width="31" /> +  <filter_editor +   text_pad_left="10" +   follows="left|top|right" +   height="23" +   label="Enter search text" +   layout="topleft" +   left_pad="3" +   max_length_chars="300" +   highlight_text_field="true" +   name="inventory search editor" +   width="177" />    <tab_container       follows="all"       halign="center" diff --git a/indra/newview/skins/default/xui/en/panel_navigation_bar.xml b/indra/newview/skins/default/xui/en/panel_navigation_bar.xml index c7edba21f8..1c9aa1eb83 100644 --- a/indra/newview/skins/default/xui/en/panel_navigation_bar.xml +++ b/indra/newview/skins/default/xui/en/panel_navigation_bar.xml @@ -151,30 +151,43 @@  	         layout="topleft"             auto_resize="true"             user_resize="true" -           min_width="185" +           min_width="342"             name="favorites_layout_panel" -           width="320"> +           width="342">             <icon               follows="top|left"               height="25"               image_name="ChatBarHandle"               layout="topleft" -             left="-323" +             left="-345"               name="resize_handle"               top="4"               width="5" /> - +           <button +             height="23" +             width="32" +             layout="topleft" +             mouse_opaque="true" +             follows="left|top" +             name="landmarks_btn" +             tool_tip="My Landmarks" +             top_delta="1" +             left_pad="8" +             scale_image="false" +             image_overlay="Landmarks_overlay" +             image_hover_unselected="PushButton_Over"> +           </button>             <favorites_bar               follows="left|right|top"               font="SansSerifSmall"               height="20"               layout="topleft" -             left="0" +             left_pad="0"               top="4"               name="favorite"               image_drag_indication="Accordion_ArrowOpened_Off"               tool_tip="Drag Landmarks here for quick access to your favorite places in Second Life!" -             width="320"> +             width="310">              <label               follows="left|top"               height="13" @@ -185,8 +198,8 @@               tool_tip="Drag Landmarks here for quick access to your favorite places in Second Life!"               top="13"  	     valign="bottom" -             width="102"> -              Favorites Bar +             width="290"> +              Places you save to your favorites bar will appear here.              </label>                <!-- More button actually is a text box. -->                <more_button diff --git a/indra/newview/skins/default/xui/en/panel_outfit_edit.xml b/indra/newview/skins/default/xui/en/panel_outfit_edit.xml index 3f7444dec3..d625f89f3b 100644 --- a/indra/newview/skins/default/xui/en/panel_outfit_edit.xml +++ b/indra/newview/skins/default/xui/en/panel_outfit_edit.xml @@ -81,7 +81,7 @@              name="title"              text_color="LtGray"              top="0" -            value="Edit Outfit" +            value="Edit outfit parts"              use_ellipses="true"              width="275" /> @@ -510,27 +510,31 @@ It is calculated as border_size + 2*UIResizeBarOverlap                  <button                          follows="bottom|left|right"                          height="23" -                        label="Save" +                        label="Save changes"                          left="1"                          layout="topleft"                          name="save_btn"                          top="0"                          width="155" /> -                <button -                        follows="bottom|right" -                        height="23" -                        name="save_flyout_btn" -                        label="" -                        layout="topleft" -                        left_pad="-20" -                        tab_stop="false" -                        top="0" -                        image_selected="SegmentedBtn_Right_Selected_Press" -                        image_unselected="SegmentedBtn_Right_Off" -                        image_pressed="SegmentedBtn_Right_Press" -                        image_pressed_selected="SegmentedBtn_Right_Selected_Press" -                        image_overlay="Arrow_Small_Up" -                        width="20"/> +            </layout_panel> +            <layout_panel +               follows="bottom|left|right" +               height="23" +               layout="bottomleft" +               left_pad="3" +               mouse_opaque="false" +               name="save_as_btn_lp" +               auto_resize="true" +               width="156"> +              <button +                   follows="bottom|left|right" +                   height="23" +                   label="Save as..." +                   layout="topleft" +                   name="save_as_btn" +                   top="0" +                   left="1" +                   width="155" />              </layout_panel>              <layout_panel                      follows="bottom|left|right" diff --git a/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml b/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml index 6c8cc9d39a..7b898dbd7f 100644 --- a/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml +++ b/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml @@ -100,28 +100,33 @@                      <button                           follows="bottom|left|right"                           height="23" -                         label="Save As" +                         label="Save changes"                           left="1"                           layout="topleft"                           name="save_btn"                           top="0"                           width="155" /> -                    <button -                         follows="bottom|right" -                         height="23" -                         name="save_flyout_btn" -                         label="" -                         layout="topleft" -                         left_pad="-20" -                         tab_stop="false" -                         image_selected="SegmentedBtn_Right_Selected_Press" -                         image_unselected="SegmentedBtn_Right_Off" -                         image_pressed="SegmentedBtn_Right_Press" -                         image_pressed_selected="SegmentedBtn_Right_Selected_Press" -                         image_overlay="Arrow_Small_Up" -                         width="20"/> -			    </layout_panel> -			    <layout_panel +          </layout_panel> +          <layout_panel +               follows="bottom|left|right" +               height="23" +               layout="bottomleft" +               left_pad="3" +               mouse_opaque="false" +               name="save_as_btn_lp" +               auto_resize="true" +               width="156"> +              <button +                   follows="bottom|left|right" +                   height="23" +                   label="Save as..." +                   layout="topleft" +                   name="save_as_btn" +                   top="0" +                   left="1" +                   width="155" /> +          </layout_panel> +          <layout_panel                       follows="bottom|left|right"                       height="23"                       layout="bottomleft" diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml index c4248d9b92..50035fd0e3 100644 --- a/indra/newview/skins/default/xui/en/panel_people.xml +++ b/indra/newview/skins/default/xui/en/panel_people.xml @@ -12,7 +12,7 @@   width="333">      <string       name="no_recent_people" -     value="No recent people. Looking for people to hang out with? Try [secondlife:///app/search/people Search] or the [secondlife:///app/worldmap World Map]." /> +     value="No recent people." />      <string       name="no_filtered_recent_people"       value="Didn't find what you're looking for? Try [secondlife:///app/search/people/[SEARCH_TERM] Search]." /> @@ -30,8 +30,13 @@       value="No friends" />      <string       name="no_friends_msg"> -         Find friends using [secondlife:///app/search/people Search] or right-click on a Resident to add them as a friend. -Looking for people to hang out with? Try the [secondlife:///app/worldmap World Map]. +      To add someone as a friend, right-click on their avatar or their name. + +Looking for places with more people? + +[secondlife:///app/floater/destinations Destination Guide] has locations chosen by Second Life staff. + +[secondlife:///app/search/ Search] lets you search all of Second Life for certain keywords.      </string>      <string       name="no_filtered_friends_msg"> @@ -45,8 +50,11 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M       name="no_filtered_groups_msg"       value="Didn't find what you're looking for? Try [secondlife:///app/search/groups/[SEARCH_TERM] Search]." />      <string -     name="no_groups_msg" -     value="Looking for Groups to join? Try [secondlife:///app/search/groups Search]." /> +     name="no_groups_msg"> +You are not a member of any groups. + +Learn about [https://community.secondlife.com/knowledgebase/joining-and-participating-in-groups-r51/ groups in Second Life.] +  </string>  	<string  	 name="MiniMapToolTipMsg"  	 value="[REGION](Double-click to open Map, shift-drag to pan)"/> diff --git a/indra/newview/skins/default/xui/en/panel_place_profile.xml b/indra/newview/skins/default/xui/en/panel_place_profile.xml index 36b7b0501b..bdde2cab20 100644 --- a/indra/newview/skins/default/xui/en/panel_place_profile.xml +++ b/indra/newview/skins/default/xui/en/panel_place_profile.xml @@ -172,7 +172,7 @@       name="back_btn"       tool_tip="Back"       tab_stop="false" -     top="4" +     top="2"       width="30"       use_draw_context_alpha="false" />      <text @@ -183,20 +183,20 @@       left_pad="10"       name="title"       text_color="LtGray" -     top="4" +     top="2"       use_ellipses="true"       value="Place Profile"       width="280" />      <scroll_container       color="DkGray2"       follows="all" -     height="572" +     height="575"       layout="topleft"       left="9"       name="place_scroll"       opaque="true" -     top_pad="10" -     width="310"> +     top_pad="9" +     width="324">          <panel           bg_alpha_color="DkGray2"           follows="left|top|right|bottom" diff --git a/indra/newview/skins/default/xui/en/panel_places.xml b/indra/newview/skins/default/xui/en/panel_places.xml index 1f32ae53ba..58be4d4c5e 100644 --- a/indra/newview/skins/default/xui/en/panel_places.xml +++ b/indra/newview/skins/default/xui/en/panel_places.xml @@ -11,30 +11,156 @@ background_visible="true"   top="0"   left="0"   width="333"> -    <string -     name="landmarks_tab_title" -     value="MY LANDMARKS" /> -    <string -     name="teleport_history_tab_title" -     value="TELEPORT HISTORY" /> -    <filter_editor -     text_pad_left="10" -     follows="left|top|right" -     font="SansSerifSmall" -     height="23" -     layout="topleft" -     left="10" -     label="Filter My Places" -     max_length_chars="300" -     name="Filter" -     tab_group="1" -     top="3" -     width="303" /> +  <string +   name="landmarks_tab_title" +   value="LANDMARKS" /> +  <string +   name="teleport_history_tab_title" +   value="VISITED" /> +  <string +   name="favorites_tab_title" +   value="FAVORITES" /> +  <string +   name="tooltip_trash_items" +   value="Remove selected landmark or folder" /> +  <string +   name="tooltip_trash_history" +   value="Delete list of visited places" /> +  <layout_stack +    animate="false" +    border_size="0" +    follows="all" +    height="564" +    layout="topleft" +    orientation="vertical" +    top="1" +    left="0" +    name="places_layout_panel" +    width="333"> +    <layout_panel +      auto_resize="true" +      height="538" +      layout="topleft" +      name="main_panel" +      width="333"> +    <layout_stack +      animate="false" +      border_size="0" +      follows="left|top|right" +      height="27" +      layout="topleft" +      orientation="horizontal" +      top="0" +      left="0" +      name="top_menu_panel" +      width="320"> +      <layout_panel +        auto_resize="true" +        layout="topleft" +        name="filter_panel" +        width="193"> +        <filter_editor +          text_pad_left="10" +          follows="left|top|right" +          font="SansSerifSmall" +          height="23" +          layout="topleft" +          left="10" +          label="Filter My Places" +          max_length_chars="300" +          name="Filter" +          tab_group="1" +          top="3" +          width="181" /> +      </layout_panel> +      <layout_panel +        auto_resize="false" +        height="25" +        layout="topleft" +        name="options_gear_btn_panel" +        width="32"> +        <menu_button +          follows="bottom|left" +          tool_tip="Show options" +          height="25" +          image_hover_unselected="Toolbar_Middle_Over" +          image_overlay="OptionsMenu_Off" +          image_selected="Toolbar_Middle_Selected" +          image_unselected="Toolbar_Middle_Off" +          menu_position="bottomleft" +          layout="topleft" +          left="0" +          name="options_gear_btn" +          top="0" +          width="31" /> +      </layout_panel> +      <layout_panel +        auto_resize="false" +        height="25" +        layout="topleft" +        name="options_sort_btn_panel" +        width="32"> +        <menu_button +          follows="bottom|left" +          tool_tip="Show sorting options" +          height="25" +          image_hover_unselected="Toolbar_Middle_Over" +          image_overlay="Conv_toolbar_sort" +          image_selected="Toolbar_Middle_Selected" +          image_unselected="Toolbar_Middle_Off" +          menu_position="bottomleft" +          layout="topleft" +          left="0" +          name="sorting_menu_btn" +          top="0" +          width="31" /> +      </layout_panel> +      <layout_panel +        auto_resize="false" +        height="25" +        layout="topleft" +        name="add_btn_panel" +        width="32"> +        <menu_button +          follows="bottom|left" +          height="25" +          image_hover_unselected="Toolbar_Middle_Over" +          image_overlay="AddItem_Off" +          image_selected="Toolbar_Middle_Selected" +          image_unselected="Toolbar_Middle_Off" +          menu_position="bottomleft" +          layout="topleft" +          left="0" +          name="add_menu_btn" +          tool_tip="Add new landmark or folder" +          top="0" +          width="31" /> +      </layout_panel> +      <layout_panel +        auto_resize="false" +        height="25" +        layout="topleft" +        name="trash_btn_panel" +        width="31"> +        <dnd_button +          follows="bottom|left" +          height="25" +          image_hover_unselected="Toolbar_Right_Over" +          image_overlay="TrashItem_Off" +          image_selected="Toolbar_Right_Selected" +          image_unselected="Toolbar_Right_Off" +          left="0" +          layout="topleft" +          name="trash_btn" +          top="0" +          width="31"/> +      </layout_panel> +    </layout_stack>      <tab_container       follows="all" -     halign="center" -     height="503"       layout="topleft" +     halign="center" +     height="504"       left="6"       name="Places Tabs"       tab_min_width="80" @@ -42,40 +168,50 @@ background_visible="true"       tab_height="30"       tab_group="2"       tab_position="top" -     top_pad="10" -     width="315" /> +     top_pad="7" +     width="318" +     visible="true"/>      <panel       class="panel_place_profile"       filename="panel_place_profile.xml"       follows="all" -     height="533"       layout="topleft" +     height="533"       left="0" +     top="4"       help_topic="place_profile"       name="panel_place_profile" -     top="5"       visible="false" -     width="315" /> +     width="318" />      <panel       class="panel_landmark_info"       filename="panel_landmark_info.xml"       follows="all" -     height="533"       layout="topleft" +     height="533"       left="0" +     top="4"       help_topic="landmark"       name="panel_landmark_info" -     top="5"       visible="false" -     width="315" /> +     width="318" /> +    </layout_panel> + +    <!--*********************** Button wrappers ***********************--> +    <layout_panel +     auto_resize="false" +     layout="topleft" +     height="25" +     name="button_layout_panel">      <panel       follows="bottom|left|right"       height="23"       layout="topleft"       left="4" +     top="2"       name="button_panel" -     width="315"> -      +     width="318"> +             <layout_stack       	follows="bottom|left|right"  		height="23" @@ -186,41 +322,6 @@ background_visible="true"  			name="lp2"  			auto_resize="true"  			width="116"> - -		<!--*********************** Profile button ***********************-->		 -				 -				<layout_stack -		     	follows="bottom|left|right" -				height="23" -				layout="topleft" -				mouse_opaque="false" -				name="bottom_bar_profile_ls" -				left="0" -				orientation="horizontal" -				top="0" -				width="110">		 -					<layout_panel -					follows="bottom|left|right" -					height="23" -					layout="bottomleft" -					left_pad="3"			 -					mouse_opaque="false" -					name="profile_btn_lp" -				    auto_resize="true" -					width="102"> -						<button -				         follows="bottom|left|right" -				         height="23" -				         label="Profile" -				         layout="topleft" -						 mouse_opaque="false" -				         name="profile_btn" -				         left="1" -				         tool_tip="Show place profile" -				         top="0" -				         width="101" />		 -					</layout_panel> -				</layout_stack>  		<!--*********************** Close button ***********************--> @@ -265,6 +366,7 @@ background_visible="true"  		<layout_stack       	follows="bottom|left|right" +      animate="false"  		height="23"  		layout="topleft"  		mouse_opaque="false" @@ -319,4 +421,6 @@ background_visible="true"  			</layout_panel>		  		</layout_stack>      </panel> +    </layout_panel> +  </layout_stack>  </panel> diff --git a/indra/newview/skins/default/xui/en/panel_settings_sky_sunmoon.xml b/indra/newview/skins/default/xui/en/panel_settings_sky_sunmoon.xml index 0e3de821d1..1ad78dbb13 100644 --- a/indra/newview/skins/default/xui/en/panel_settings_sky_sunmoon.xml +++ b/indra/newview/skins/default/xui/en/panel_settings_sky_sunmoon.xml @@ -38,7 +38,7 @@                      height="10"                      layout="topleft"                      left_delta="10" -                    top_delta="30" +                    top_delta="25"                      width="100">                  Position:              </text> @@ -93,7 +93,7 @@                      follows="left|top"                      height="10"                      layout="topleft" -                    left_delta="-5" +                    left_delta="65"                      top_delta="20"                      width="80">                  Color: @@ -108,12 +108,58 @@                      name="sun_moon_color"                      top_pad="5"                      width="60" /> +          <text +            follows="left|top" +            height="10" +            layout="topleft" +            left_delta="-235" +            top_delta="-3" +            width="200"> +            Azimuth: +          </text> +          <slider +            decimal_digits="2" +            follows="left|top" +            height="16" +            increment="0.01" +            initial_value="0" +            layout="topleft" +            left_delta="5" +            min_val="0" +            max_val="359.99" +            name="sun_azimuth" +            top_delta="13" +            width="215" +            can_edit_text="true"/> +          <text +            follows="left|top" +            height="10" +            layout="topleft" +            left_delta="-5" +            top_delta="22" +            width="200"> +            Elevation: +          </text> +          <slider +            decimal_digits="2" +            follows="left|top" +            height="16" +            increment="0.01" +            initial_value="0" +            layout="topleft" +            left_delta="5" +            min_val="-90" +            max_val="90" +            name="sun_elevation" +            top_delta="13" +            width="215" +            can_edit_text="true"/>              <text                      follows="left|top"                      height="10"                      layout="topleft" -                    left_delta="-160" -                    top_delta="27" +                    left_delta="-5" +                    top_delta="22"                      width="200">                  Glow Focus:              </text> @@ -128,8 +174,8 @@                      min_val="-2"                      max_val="2"                      name="glow_focus" -                    top_delta="15" -                    width="250" +                    top_delta="13" +                    width="215"                      can_edit_text="true"/>              <text                      follows="left|top" @@ -151,8 +197,8 @@                      min_val="0"                      max_val="1.99"                      name="glow_size" -                    top_delta="15" -                    width="250" +                    top_delta="13" +                    width="215"                      can_edit_text="true"/>              <text                      follows="left|top" @@ -174,20 +220,20 @@                      min_val="0"                      max_val="500"                      name="star_brightness" -                    top_delta="15" -                    width="250" +                    top_delta="13" +                    width="215"                      can_edit_text="true"/>              <check_box                      control_name="sunbeacon" +                    follows="left|top" +                    layout="topleft"                      width="60"                      height="16"                      label="Show Beacon" -                    layout="topleft" -                    name="sunbeacon"  -                    right="-50" -                    bottom="-10" -                    follows="bottom|right"/> +                    name="sunbeacon" +                    top_pad="5" +                    left_delta="-8"/>          </layout_panel>          <layout_panel @@ -227,7 +273,7 @@                              height="10"                              layout="topleft"                              left_delta="10" -                            top_delta="30" +                            top_delta="25"                              width="100">                          Position:                      </text> @@ -278,39 +324,85 @@                              top_delta="15"                              width="130"                              can_edit_text="true"/> -                    <text -                            follows="left|top" -                            height="10" -                            layout="topleft" -                            left_delta="-5" -                            top_delta="22" -                            width="200"> -                        Brightness: -                    </text> -                    <slider -                            decimal_digits="2" -                            follows="left|top" -                            height="16" -                            increment="0.01" -                            initial_value="0" -                            layout="topleft" -                            left_delta="5" -                            min_val="0.0" -                            max_val="1.0" -                            name="moon_brightness" -                            top_delta="15" -                            width="130" -                            can_edit_text="true"/> -                <check_box +                  <text +                    follows="left|top" +                    height="10" +                    layout="topleft" +                    left_delta="-170" +                    top_delta="32" +                    width="200"> +                    Azimuth: +                  </text> +                  <slider +                    decimal_digits="2" +                    follows="left|top" +                    height="16" +                    increment="0.01" +                    initial_value="0" +                    layout="topleft" +                    left_delta="5" +                    min_val="0" +                    max_val="359.99" +                    name="moon_azimuth" +                    top_delta="13" +                    width="215" +                    can_edit_text="true"/> +                  <text +                    follows="left|top" +                    height="10" +                    layout="topleft" +                    left_delta="-5" +                    top_delta="22" +                    width="200"> +                    Elevation: +                  </text> +                  <slider +                    decimal_digits="2" +                    follows="left|top" +                    height="16" +                    increment="0.01" +                    initial_value="0" +                    layout="topleft" +                    left_delta="5" +                    min_val="-90" +                    max_val="90" +                    name="moon_elevation" +                    top_delta="13" +                    width="215" +                    can_edit_text="true"/> +                  <text +                    follows="left|top" +                    height="10" +                    layout="topleft" +                    left_delta="-5" +                    top_delta="22" +                    width="200"> +                    Brightness: +                  </text> +                  <slider +                    decimal_digits="2" +                    follows="left|top" +                    height="16" +                    increment="0.01" +                    initial_value="0" +                    layout="topleft" +                    left_delta="5" +                    min_val="0.0" +                    max_val="1.0" +                    name="moon_brightness" +                    top_delta="13" +                    width="215" +                    can_edit_text="true"/> +                  <check_box                          control_name="moonbeacon" +                        follows="left|top" +                        layout="topleft"                          width="60"                          height="16"                          label="Show Beacon" -                        layout="topleft"                          name="moonbeacon"  -                        right="-50" -                        bottom="-10" -                        follows="bottom|right"/> +                        top_pad="5" +                        left_delta="-8"/>                  </layout_panel>              </layout_stack> diff --git a/indra/newview/skins/default/xui/en/panel_status_bar.xml b/indra/newview/skins/default/xui/en/panel_status_bar.xml index ada980cda1..9023d68ea9 100644 --- a/indra/newview/skins/default/xui/en/panel_status_bar.xml +++ b/indra/newview/skins/default/xui/en/panel_status_bar.xml @@ -35,7 +35,7 @@      </panel.string>    <panel  	 height="18" -	 left="-458" +	 left="-398"  	 top="0"  	 width="120"  	 follows="right|top" @@ -75,7 +75,7 @@    </panel>    <panel      height="18" -    left="-458" +    left="-398"      width="185"      top="1"      follows="right|top"  @@ -142,7 +142,7 @@       left_pad="0"       name="TimeText"       tool_tip="Current time (Pacific)" -     width="145"> +     width="85">          24:00 AM PST      </text>      <icon diff --git a/indra/newview/skins/default/xui/en/panel_teleport_history.xml b/indra/newview/skins/default/xui/en/panel_teleport_history.xml index 768efc2f3f..55c47c90a4 100644 --- a/indra/newview/skins/default/xui/en/panel_teleport_history.xml +++ b/indra/newview/skins/default/xui/en/panel_teleport_history.xml @@ -6,7 +6,7 @@       bg_alpha_color="DkGray">           <accordion       follows="left|top|right|bottom" -     height="373" +     height="400"       layout="topleft"       left="3"       top="0" @@ -147,37 +147,4 @@  	        </flat_list_view>  	    </accordion_tab>      </accordion> -    <panel -     background_visible="true" -     bevel_style="none" -     bottom="0" -     follows="left|right|bottom" -     height="27" -     layout="bottomleft" -     left="3" -     name="bottom_panel" -     width="313"> -        <menu_button -         follows="bottom|left" -         tool_tip="Show additional options" -         height="25" -         image_hover_unselected="Toolbar_Left_Over" -         image_overlay="OptionsMenu_Off" -         image_selected="Toolbar_Left_Selected" -         image_unselected="Toolbar_Left_Off" -         layout="topleft" -         left="0" -         name="gear_btn" -         top="1" -         width="31" /> -        <icon -         follows="bottom|left|right" -         height="25" -         image_name="Toolbar_Right_Off" -         layout="topleft" -         left_pad="1" -         name="dummy_icon" -         width="273" -        /> -    </panel>  </panel> diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index 7ed3a2501d..e50277ccd7 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -2296,9 +2296,9 @@ For AI Character: Get the closest navigable point to the point provided.  	<!-- inventory -->  	<string name="InventoryNoMatchingItems">Didn't find what you're looking for? Try [secondlife:///app/search/all/[SEARCH_TERM] Search].</string> -	<string name="InventoryNoMatchingRecentItems">Didn't find what you're looking for? Try [secondlife:///app/inventory/filters Show filters].</string> -	<string name="PlacesNoMatchingItems">Didn't find what you're looking for? Try [secondlife:///app/search/places/[SEARCH_TERM] Search].</string> -	<string name="FavoritesNoMatchingItems">Drag a landmark here to add it to your favorites.</string> +	<string name="InventoryNoMatchingRecentItems">Didn't find what you're looking for? Try [secondlife:///app/inventory/filters Show filters].</string>	 +	<string name="PlacesNoMatchingItems">To add a place to your landmarks, click the star to the right of the location name.</string> +	<string name="FavoritesNoMatchingItems">To add a place to your favorites, click the star to the right of the location name, then save the landmark to "Favorites bar".</string>  	<string name="MarketplaceNoListing">You have no listings yet.</string>  	<string name="MarketplaceNoMatchingItems">No items found. Check the spelling of your search string and try again.</string>  	<string name="InventoryNoTexture">You do not have a copy of this texture in your inventory</string> @@ -2418,6 +2418,7 @@ If you continue to receive this message, please contact Second Life support for  	<string name="Scripts"       value=" Scripts," />  	<string name="Sounds"        value=" Sounds," />  	<string name="Textures"      value=" Textures," /> +	<string name="Settings"      value=" Settings," />  	<string name="Snapshots"     value=" Snapshots," />  	<string name="No Filters"    value="No " />  	<string name="Since Logoff"  value=" - Since Logoff" /> @@ -2839,7 +2840,6 @@ If you continue to receive this message, please contact Second Life support for  	<string name="AcquiredItems">Acquired Items</string>  	<string name="Cancel">Cancel</string>  	<string name="UploadingCosts">Uploading [NAME] costs L$ [AMOUNT]</string> -	<string name="BuyingCosts">Buying this costs L$ [AMOUNT]</string>  	<string name="UnknownFileExtension">  		Unknown file extension .%s  Expected .wav, .tga, .bmp, .jpg, .jpeg, or .anim @@ -3763,6 +3763,9 @@ If you continue to receive this message, contact the [SUPPORT_SITE].    <string name="unread_chat_multiple">      [SOURCES] have said something new    </string> +  <string name="teleport_preamble_compact_chat"> +    You are now at +  </string>  	<string name="session_initialization_timed_out_error">  		The session initialization is timed out  	</string> @@ -3772,6 +3775,10 @@ If you continue to receive this message, contact the [SUPPORT_SITE].    <string name="voice_morphing_url">https://secondlife.com/destination/voice-island</string>    <string name="premium_voice_morphing_url">https://secondlife.com/destination/voice-morphing-premium</string> +  <string name="lindenhomes_get_home_url">https://secondlife.com/land/lindenhomes/member.php</string> +  <string name="lindenhomes_my_home_url">https://land.secondlife.com/en-Us/lindenhomes/my-home.php</string> +  <string name="membership_url">https://secondlife.com/my/account/membership.php</string> +    <!-- Financial operations strings -->    <string name="paid_you_ldollars">[NAME] paid you L$[AMOUNT] [REASON].</string>    <string name="paid_you_ldollars_gift">[NAME] paid you L$[AMOUNT]: [REASON]</string> @@ -3795,11 +3802,12 @@ If you continue to receive this message, contact the [SUPPORT_SITE].    <string name="to upload">to upload</string>    <string name="to publish a classified ad">to publish a classified ad</string> -  <string name="giving">Giving L$ [AMOUNT]</string>    <string name="uploading_costs">Uploading costs L$ [AMOUNT]</string>    <string name="this_costs">This costs L$ [AMOUNT]</string> -  <string name="buying_selected_land">Buying selected land for L$ [AMOUNT]</string> -  <string name="this_object_costs">This object costs L$ [AMOUNT]</string> +   +  <string name="buying_selected_land">This land costs</string> +  <string name="this_object_costs">This item costs</string> +  <string name="giving">You want to give</string>    <string name="group_role_everyone">Everyone</string>    <string name="group_role_officers">Officers</string> @@ -3962,6 +3970,9 @@ Please check http://status.secondlifegrid.net to see if there is a known problem    <string name="Premium PlusMembership">Premium Plus</string>    <string name="InternalMembership">Internal</string> <!-- No need to translate --> +  <string name="MembershipUpgradeText">Upgrade to Premium</string> +  <string name="MembershipPremiumText">My Premium membership</string> +    <!-- Question strings for delete items notifications -->    <string name="DeleteItems">Delete selected items?</string>    <string name="DeleteItem">Delete selected item?</string> @@ -4118,8 +4129,8 @@ Try enclosing path to the editor with double quotes.    <!-- commands -->    <string name="Command_AboutLand_Label">About land</string> -  <string name="Command_Appearance_Label">Appearance</string> -  <string name="Command_Avatar_Label">Avatar</string> +  <string name="Command_Appearance_Label">Outfits</string> +  <string name="Command_Avatar_Label">Complete avatars</string>    <string name="Command_Build_Label">Build</string>    <string name="Command_Chat_Label">Chat</string>    <string name="Command_Conversations_Label">Conversations</string> @@ -4128,7 +4139,7 @@ Try enclosing path to the editor with double quotes.    <string name="Command_Environments_Label">My Environments</string>    <string name="Command_Gestures_Label">Gestures</string>    <string name="Command_Grid_Status_Label">Grid status</string> -  <string name="Command_HowTo_Label">How to</string> +  <string name="Command_HowTo_Label">Guidebook</string>    <string name="Command_Inventory_Label">Inventory</string>    <string name="Command_Map_Label">Map</string>    <string name="Command_Marketplace_Label">Marketplace</string> diff --git a/indra/newview/skins/default/xui/en/teleport_strings.xml b/indra/newview/skins/default/xui/en/teleport_strings.xml index 57f8bb542d..1456114b25 100644 --- a/indra/newview/skins/default/xui/en/teleport_strings.xml +++ b/indra/newview/skins/default/xui/en/teleport_strings.xml @@ -2,8 +2,7 @@  <teleport_messages>  	<message_set name="errors">  		<message name="invalid_tport"> -			Problem encountered processing your teleport request. You may need to log back in before you can teleport. -If you continue to get this message, please check the [SUPPORT_SITE]. +			Teleport attempts are limited to 6 per minute. If you are having trouble, wait one minute and try teleporting again. If the problem persists, log out and log in again.  		</message>  		<message name="invalid_region_handoff">  			Problem encountered processing your region crossing. You may need to log back in before you can cross regions. diff --git a/indra/newview/skins/default/xui/en/widgets/filter_editor.xml b/indra/newview/skins/default/xui/en/widgets/filter_editor.xml index 2cc4abdd30..1c4822b8d5 100644 --- a/indra/newview/skins/default/xui/en/widgets/filter_editor.xml +++ b/indra/newview/skins/default/xui/en/widgets/filter_editor.xml @@ -6,9 +6,11 @@    text_pad_left="7"    select_on_focus="true"    text_tentative_color="TextFgTentativeColor" +  highlight_text_field="false"    background_image="TextField_Search_Off"    background_image_disabled="TextField_Search_Disabled" -  background_image_focused="TextField_Search_Active"> +  background_image_focused="TextField_Search_Active" +  background_image_highlight="TextField_Search_Highlight">    <search_button label=""      top_pad="4"      left_pad="4" diff --git a/indra/newview/skins/default/xui/en/widgets/search_editor.xml b/indra/newview/skins/default/xui/en/widgets/search_editor.xml index faa0404b35..dc5a07bf4f 100644 --- a/indra/newview/skins/default/xui/en/widgets/search_editor.xml +++ b/indra/newview/skins/default/xui/en/widgets/search_editor.xml @@ -7,9 +7,11 @@    text_pad_right="6"     select_on_focus="true"    text_tentative_color="TextFgTentativeColor" +  highlight_text_field="false"    background_image="TextField_Search_Off"    background_image_disabled="TextField_Search_Disabled" -  background_image_focused="TextField_Search_Active" > +  background_image_focused="TextField_Search_Active" +  background_image_highlight="TextField_Search_Highlight">    <search_button       top_pad="4"      left_pad="4"  diff --git a/indra/newview/tests/cppfeatures_test.cpp b/indra/newview/tests/cppfeatures_test.cpp new file mode 100644 index 0000000000..923bb1e1b2 --- /dev/null +++ b/indra/newview/tests/cppfeatures_test.cpp @@ -0,0 +1,386 @@ +/** + * @file cppfeatures_test + * @author Vir + * @date 2021-03 + * @brief cpp features + * + * $LicenseInfo:firstyear=2021&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2021, 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$ + */ + +// Tests related to newer C++ features, for verifying support across compilers and platforms + +#include "linden_common.h" +#include "../test/lltut.h" + +namespace tut +{ + +struct cpp_features_test {}; +typedef test_group<cpp_features_test> cpp_features_test_t; +typedef cpp_features_test_t::object cpp_features_test_object_t; +tut::cpp_features_test_t tut_cpp_features_test("LLCPPFeatures"); + +// bracket initializers +// Can initialize containers or values using curly brackets +template<> template<> +void cpp_features_test_object_t::test<1>() +{ +	S32 explicit_val{3}; +	ensure(explicit_val==3); + +	S32 default_val{}; +	ensure(default_val==0); +	 +	std::vector<S32> fibs{1,1,2,3,5}; +	ensure(fibs[4]==5); +} + +// auto +// +// https://en.cppreference.com/w/cpp/language/auto +//  +// Can use auto in place of a more complex type specification, if the compiler can infer the type +template<> template<> +void cpp_features_test_object_t::test<2>() +{ +	std::vector<S32> numbers{3,6,9}; + +	// auto element +	auto& aval = numbers[1]; +	ensure("auto element", aval==6); + +	// auto iterator (non-const) +	auto it = numbers.rbegin(); +	*it += 1; +	S32 val = *it; +	ensure("auto iterator", val==10); +} + +// range for +// +// https://en.cppreference.com/w/cpp/language/range-for +// +// Can iterate over containers without explicit iterator +template<> template<> +void cpp_features_test_object_t::test<3>() +{ + +	// Traditional iterator for with container +	// +	// Problems: +	// * Have to create a new variable for the iterator, which is unrelated to the problem you're trying to solve. +	// * Redundant and somewhat fragile. Have to make sure begin() and end() are both from the right container. +	std::vector<S32> numbers{3,6,9}; +	for (auto it = numbers.begin(); it != numbers.end(); ++it) +	{ +		auto& n = *it; +		n *= 2; +	} +	ensure("iterator for vector", numbers[2]==18); + +	// Range for with container +	// +	// Under the hood, this is doing the same thing as the traditional +	// for loop above. Still uses begin() and end() but you don't have +	// to access them directly. +	std::vector<S32> numbersb{3,6,9}; +	for (auto& n: numbersb) +	{ +		n *= 2; +	} +	ensure("range for vector", numbersb[2]==18); + +	// Range for over a C-style array. +	// +	// This is handy because the language determines the range automatically. +	// Getting this right manually is a little trickier. +	S32 pows[] = {1,2,4,8,16}; +	S32 sum{}; +	for (const auto& v: pows) +	{ +		sum += v; +	} +	ensure("for C-array", sum==31); +} + +// override specifier +// +// https://en.cppreference.com/w/cpp/language/override +// +// Specify that a particular class function is an override of a virtual function. +// Benefits: +// * Makes code somewhat easier to read by showing intent. +// * Prevents mistakes where you think something is an override but it doesn't actually match the declaration in the parent class. +// Drawbacks: +// * Some compilers require that any class using override must use it consistently for all functions.  +//   This makes switching a class to use override a lot more work.  + +class Foo +{ +public: +	virtual bool is_happy() const = 0; +}; + +class Bar: public Foo +{ +public: +	bool is_happy() const override { return true; }  +	// Override would fail: non-const declaration doesn't match parent  +	// bool is_happy() override { return true; }  +	// Override would fail: wrong name +	// bool is_happx() override { return true; }  +}; + +template<> template<> +void cpp_features_test_object_t::test<4>() +{ +	Bar b; +	ensure("override", b.is_happy()); +} + +// final +// +// https://en.cppreference.com/w/cpp/language/final: "Specifies that a +// virtual function cannot be overridden in a derived class or that a +// class cannot be inherited from." + +class Vehicle +{ +public: +	virtual bool has_wheels() const = 0; +}; + +class WheeledVehicle: public Vehicle +{ +public: +	virtual bool has_wheels() const final override { return true; } +}; + +class Bicycle: public WheeledVehicle +{ +public: +	// Error: can't override final version in WheeledVehicle  +	// virtual bool has_wheels() override const { return true; } +}; + +template<> template<> +void cpp_features_test_object_t::test<5>() +{ +	Bicycle bi; +	ensure("final", bi.has_wheels()); +} + +// deleted function declaration +// +// https://en.cppreference.com/w/cpp/language/function#Deleted_functions +// +// Typical case: copy constructor doesn't make sense for a particular class, so you want to make +// sure the no one tries to copy-construct an instance of the class, and that the +// compiler won't generate a copy constructor for  you automatically. +// Traditional fix is to declare a +// copy constructor but never implement it, giving you a link-time error if anyone tries to use it. +// Now you can explicitly declare a function to be deleted, which has at least two advantages over +// the old way: +// * Makes the intention clear +// * Creates an error sooner, at compile time + +class DoNotCopy +{ +public: +	DoNotCopy() {} +	DoNotCopy(const DoNotCopy& ref) = delete; +}; + +template<> template<> +void cpp_features_test_object_t::test<6>() +{ +	DoNotCopy nc; // OK, default constructor +	//DoNotCopy nc2(nc); // No, can't copy +	//DoNotCopy nc3 = nc; // No, this also calls copy constructor (even though it looks like an assignment) +} + +// defaulted function declaration +// +// https://en.cppreference.com/w/cpp/language/function#Function_definition +// +// What about the complementary case to the deleted function declaration, where you want a copy constructor +// and are happy with the default implementation the compiler will make (memberwise copy). +// Now you can explicitly declare that too. +// Usage: I guess it makes the intent clearer, but otherwise not obviously useful. +class DefaultCopyOK +{ +public: +	DefaultCopyOK(): mVal(123) {} +	DefaultCopyOK(const DefaultCopyOK&) = default; +	S32 val() const { return mVal; } +private: +	S32 mVal; +}; + +template<> template<> +void cpp_features_test_object_t::test<7>() +{ +	DefaultCopyOK d; // OK +	DefaultCopyOK d2(d); // OK +	DefaultCopyOK d3 = d; // OK +	ensure("default copy d", d.val()==123); +	ensure("default copy d2", d.val()==d2.val()); +	ensure("default copy d3", d.val()==d3.val()); +} + +// initialize class members inline +// +// https://en.cppreference.com/w/cpp/language/data_members#Member_initialization +// +// Default class member values can be set where they are declared, using either brackets or = + +// It is preferred to skip creating a constructor if all the work can be done by inline initialization: +// http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines.html#c45-dont-define-a-default-constructor-that-only-initializes-data-members-use-in-class-member-initializers-instead +// +class InitInline +{ +public: +	S32 mFoo{10}; +}; + +class InitInlineWithConstructor +{ +public: +	// Here mFoo is not specified, so you will get the default value of 10. +	// mBar is specified, so 25 will override the default value. +	InitInlineWithConstructor(): +		mBar(25) +	{} + +	// Default values set using two different styles, same effect. +	S32 mFoo{10}; +	S32 mBar = 20; +}; + +template<> template<> +void cpp_features_test_object_t::test<8>() +{ +	InitInline ii; +	ensure("init member inline 1", ii.mFoo==10); + +	InitInlineWithConstructor iici; +	ensure("init member inline 2", iici.mFoo=10); +	ensure("init member inline 3", iici.mBar==25); +} + +// constexpr +// +// https://en.cppreference.com/w/cpp/language/constexpr +// +// Various things can be computed at compile time, and flagged as constexpr. +constexpr S32 compute2() { return 2; } + +constexpr S32 ce_factorial(S32 n) +{ +	if (n<=0) +	{ +		return 1; +	} +	else +	{ +		return n*ce_factorial(n-1); +	} +} + +template<> template<> +void cpp_features_test_object_t::test<9>() +{ +	S32 val = compute2(); +	ensure("constexpr 1", val==2); + +	// Compile-time factorial. You used to need complex templates to do something this useless. +	S32 fac5 = ce_factorial(5); +	ensure("constexpr 2", fac5==120); +} + +// static assert +// +// https://en.cppreference.com/w/cpp/language/static_assert +// +// You can add asserts to be checked at compile time. The thing to be checked must be a constexpr. +// There are two forms: +// * static_assert(expr); +// * static_assert(expr, message); +// +// Currently only the 2-parameter form works on windows. The 1-parameter form needs a flag we don't set. + +template<> template<> +void cpp_features_test_object_t::test<10>() +{ +	// static_assert(ce_factorial(6)==720); No, needs a flag we don't currently set. +	static_assert(ce_factorial(6)==720, "bad factorial"); // OK +} + +// type aliases +// +// https://en.cppreference.com/w/cpp/language/type_alias +//  +// You can use the "using" statement to create simpler templates that +// are aliases for more complex ones. "Template typedef" + +// This makes stringmap<T> an alias for std::map<std::string, T> +template<typename T> +using stringmap = std::map<std::string, T>; + +template<> template<> +void cpp_features_test_object_t::test<11>() +{ +	stringmap<S32> name_counts{ {"alice", 3}, {"bob", 2} }; +	ensure("type alias", name_counts["bob"]==2); +} + +// Other possibilities: + +// nullptr + +// class enums + +// std::unique_ptr and make_unique + +// std::shared_ptr and make_shared + +// lambdas + +// perfect forwarding + +// variadic templates + +// std::thread + +// std::mutex + +// thread_local + +// rvalue reference && + +// move semantics + +// std::move + +// string_view + +} // namespace tut diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index adac7af712..6194328759 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -683,11 +683,6 @@ class WindowsManifest(ViewerManifest):                  self.path("libvlccore.dll")                  self.path("plugins/") -        # pull in the crash logger from other projects -        # tag:"crash-logger" here as a cue to the exporter -        self.path(src='../win_crash_logger/%s/windows-crash-logger.exe' % self.args['configuration'], -                  dst="win_crash_logger.exe") -          if not self.is_packaging_viewer():              self.package_file = "copied_deps"     @@ -1068,10 +1063,8 @@ class DarwinManifest(ViewerManifest):                  # our apps                  executable_path = {} -                for app_bld_dir, app in (("mac_crash_logger", "mac-crash-logger.app"), -                                         # plugin launcher -                                         (os.path.join("llplugin", "slplugin"), "SLPlugin.app"), -                                         ): +                embedded_apps = [ (os.path.join("llplugin", "slplugin"), "SLPlugin.app") ] +                for app_bld_dir, app in embedded_apps:                      self.path2basename(os.path.join(os.pardir,                                                      app_bld_dir, self.args['configuration']),                                         app) diff --git a/indra/test/CMakeLists.txt b/indra/test/CMakeLists.txt index 87536e146b..251100867f 100644 --- a/indra/test/CMakeLists.txt +++ b/indra/test/CMakeLists.txt @@ -13,7 +13,7 @@ include(LLXML)  include(Linking)  include(Tut)  include(LLAddBuildTest) - +include(bugsplat)  include(GoogleMock)  include_directories( @@ -83,6 +83,10 @@ list(APPEND test_SOURCE_FILES ${test_HEADER_FILES})  add_executable(lltest ${test_SOURCE_FILES}) +if (USE_BUGSPLAT) +  set_target_properties(lltest PROPERTIES COMPILE_DEFINITIONS "${BUGSPLAT_DEFINE}") +endif (USE_BUGSPLAT) +  target_link_libraries(lltest      ${LEGACY_STDIO_LIBS}      ${LLDATABASE_LIBRARIES} diff --git a/indra/win_crash_logger/README.txt b/indra/win_crash_logger/README.txt new file mode 100644 index 0000000000..6932a8d9c3 --- /dev/null +++ b/indra/win_crash_logger/README.txt @@ -0,0 +1,3 @@ +This component is no longer used in Linden Lab builds. +Change requests to support continued use by open source +builds are welcome. diff --git a/indra/win_crash_logger/llcrashloggerwindows.cpp b/indra/win_crash_logger/llcrashloggerwindows.cpp index 267224a79b..0cbe0b0d17 100644 --- a/indra/win_crash_logger/llcrashloggerwindows.cpp +++ b/indra/win_crash_logger/llcrashloggerwindows.cpp @@ -498,7 +498,7 @@ bool LLCrashLoggerWindows::frame()  		MSG msg;  		memset(&msg, 0, sizeof(msg)); -		while (!LLApp::isQuitting() && GetMessage(&msg, NULL, 0, 0)) +		while (!LLApp::isExiting() && GetMessage(&msg, NULL, 0, 0))  		{  			TranslateMessage(&msg);  			DispatchMessage(&msg); diff --git a/scripts/metrics/viewerstats.py b/scripts/metrics/viewerstats.py new file mode 100755 index 0000000000..f7be3d967e --- /dev/null +++ b/scripts/metrics/viewerstats.py @@ -0,0 +1,226 @@ +#!runpy.sh + +"""\ + +This module contains code for analyzing ViewerStats data as uploaded by the viewer. + +$LicenseInfo:firstyear=2021&license=viewerlgpl$ +Second Life Viewer Source Code +Copyright (C) 2021, 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$ +""" + +import argparse +import numpy as np +import pandas as pd +import json +from collections import Counter, defaultdict +from llbase import llsd +import io +import re +import os +import sys + +def show_stats_by_key(recs,indices,settings_sd = None): +    result = () +    cnt = Counter() +    per_key_cnt = defaultdict(Counter) +    for r in recs: +        try: +            d = r +            for idx in indices: +                d = d[idx] +            for k,v in d.items(): +                if isinstance(v,dict): +                    continue +                cnt[k] += 1 +                if isinstance(v,list): +                    v = tuple(v) +                per_key_cnt[k][v] += 1 +        except Exception as e: +            print "err", e +            print "d", d, "k", k, "v", v +            raise +    mc = cnt.most_common() +    print "=========================" +    keyprefix = "" +    if len(indices)>0: +        keyprefix = ".".join(indices) + "." +    for i,m in enumerate(mc): +        k = m[0] +        bigc = m[1] +        unset_cnt = len(recs) - bigc +        kmc = per_key_cnt[k].most_common(5) +        print i, keyprefix+str(k), bigc +        if settings_sd is not None and k in settings_sd and "Value" in settings_sd[k]: +            print "    ", "default",settings_sd[k]["Value"],"count",unset_cnt +        for v in kmc: +            print "    ", "value",v[0],"count",v[1] +    if settings_sd is not None: +        print "Total keys in settings", len(settings_sd.keys()) +        unused_keys = list(set(settings_sd.keys()) - set(cnt.keys())) +        unused_keys_non_str = [k for k in unused_keys if settings_sd[k]["Type"] != "String"] +        unused_keys_str = [k for k in unused_keys if settings_sd[k]["Type"] == "String"] + +        # Things that no one in the sample has set to a non-default value. Possible candidates for removal. +        print "\nUnused_keys_non_str", len(unused_keys_non_str) +        print   "======================" +        print "\n".join(sorted(unused_keys_non_str)) + +        # Strings are not currently logged, so we have no info on usage. +        print "\nString keys (usage unknown)", len(unused_keys_str) +        print   "======================" +        print "\n".join(sorted(unused_keys_str)) + +        # Things that someone has set but that aren't recognized settings. +        unrec_keys = list(set(cnt.keys()) - set(settings_sd.keys())) +        print "\nUnrecognized keys", len(unrec_keys) +        print   "======================" +        print "\n".join(sorted(unrec_keys)) + +        result = (settings_sd.keys(), unused_keys_str, unused_keys_non_str, unrec_keys) +    return result + +def parse_settings_xml(fname): +    # assume we're in scripts/metrics +    fname = "../../indra/newview/app_settings/" + fname +    with open(fname,"r") as f: +        contents = f.read() +        return llsd.parse_xml(contents) + +def read_raw_settings_xml(fname): +    # assume we're in scripts/metrics +    fname = "../../indra/newview/app_settings/" + fname +    contents = None +    with open(fname,"r") as f: +        contents = f.read() +    return contents + +def write_settings_xml(fname, contents): +    # assume we're in scripts/metrics +    fname = "../../indra/newview/app_settings/" + fname +    with open(fname,"w") as f: +        f.write(llsd.format_pretty_xml(contents)) +        f.close() + +def write_raw_settings_xml(fname, string): +    # assume we're in scripts/metrics +    fname = "../../indra/newview/app_settings/" + fname +    with io.open(fname,"w", newline='\n') as f: +        f.write(string.decode('latin1')) +        f.close() + +def remove_settings(string, to_remove): +    for r in to_remove: +        subs_str = r"<key>" + r + r"<.*?</map>\n" +        string = re.sub(subs_str,"",string,flags=re.S|re.DOTALL) +    return string + +def get_used_strings(root_dir): +    used_str = set() +    skipped_ext = set() +    for dir_name, sub_dir_list, file_list in os.walk(root_dir): +        for fname in file_list: +            if fname in ["settings.xml", "settings.xml.edit", "settings_per_account.xml"]: +                print "skip", fname +                continue +            (base,ext) = os.path.splitext(fname) +            #if ext not in [".cpp", ".hpp", ".h", ".xml"]: +            #    skipped_ext.add(ext) +            #    continue +             +            full_name = os.path.join(dir_name,fname) + +            with open(full_name,"r") as f: +                #print full_name +                lines = f.readlines() +                for l in lines: +                    ms = re.findall(r'[>\"]([A-Za-z0-9_]+)[\"<]',l) +                    for m in ms: +                        #print "used_str",m +                        used_str.add(m) +    print "skipped extensions", skipped_ext +    print "got used_str", len(used_str) +    return used_str +                 +     +if __name__ == "__main__": + +    parser = argparse.ArgumentParser(description="process tab-separated table containing viewerstats logs") +    parser.add_argument("--verbose", action="store_true",help="verbose flag") +    parser.add_argument("--preferences", action="store_true", help="analyze preference info") +    parser.add_argument("--remove_unused", action="store_true", help="remove unused preferences") +    parser.add_argument("--column", help="name of column containing viewerstats info") +    parser.add_argument("infiles", nargs="+", help="name of .tsv files to process") +    args = parser.parse_args() + +    for fname in args.infiles: +        print "process", fname +        df = pd.read_csv(fname,sep='\t') +        #print "DF", df.describe() +        jstrs = df['RAW_LOG:BODY'] +        #print "JSTRS", jstrs.describe() +        recs = [] +        for i,jstr in enumerate(jstrs): +            recs.append(json.loads(jstr)) +        show_stats_by_key(recs,[]) +        show_stats_by_key(recs,["agent"]) +        if args.preferences: +            print "\nSETTINGS.XML" +            settings_sd = parse_settings_xml("settings.xml") +            #for skey,svals in settings_sd.items():  +            #    print skey, "=>", svals +            (all_str,_,_,_) = show_stats_by_key(recs,["preferences","settings"],settings_sd) +            print + +            #print "\nSETTINGS_PER_ACCOUNT.XML" +            #settings_pa_sd = parse_settings_xml("settings_per_account.xml") +            #show_stats_by_key(recs,["preferences","settings_per_account"],settings_pa_sd) + +            if args.remove_unused: +                # walk codebase looking for strings +                all_str_set = set(all_str) +                used_strings = get_used_strings("../../indra") +                used_strings_set = set(used_strings) +                unref_strings = all_str_set-used_strings_set +                # Some settings names are generated by appending to a prefix. Need to look for this case. +                prefix_used = set() +                print "checking unref_strings", len(unref_strings) +                for u in unref_strings: +                    for k in range(6,len(u)): +                        prefix = u[0:k] +                        if prefix in all_str_set and prefix in used_strings_set: +                            prefix_used.add(u) +                            #print "PREFIX_USED",u,prefix +                print "PREFIX_USED", len(prefix_used), ",".join(list(prefix_used)) +                print +                unref_strings = unref_strings - prefix_used +                         +                print "\nUNREF_IN_CODE " + str(len(unref_strings)) + "\n" +                print "\n".join(list(unref_strings)) +                settings_str = read_raw_settings_xml("settings.xml") +                # Do this via direct string munging to generate minimal changeset +                settings_edited = remove_settings(settings_str,unref_strings) +                write_raw_settings_xml("settings.xml.edit",settings_edited) +                     + + + +         +      | 
