diff --git a/indra/cmake/00-Common.cmake b/indra/cmake/00-Common.cmake index 4e1e6cb493..7c1e6119cc 100644 --- a/indra/cmake/00-Common.cmake +++ b/indra/cmake/00-Common.cmake @@ -7,9 +7,7 @@ set(${CMAKE_CURRENT_LIST_FILE}_INCLUDED "YES") include(Variables) - # Portable compilation flags. - set(CMAKE_CXX_FLAGS_DEBUG "-D_DEBUG -DLL_DEBUG=1") set(CMAKE_CXX_FLAGS_RELEASE "-DLL_RELEASE=1 -DLL_RELEASE_FOR_DOWNLOAD=1 -D_SECURE_SCL=0 -DNDEBUG") @@ -31,12 +29,11 @@ if(NON_RELEASE_CRASH_REPORTING) set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DLL_SEND_CRASH_REPORTS=1") endif() - # Don't bother with a MinSizeRel build. - set(CMAKE_CONFIGURATION_TYPES "RelWithDebInfo;Release;Debug" CACHE STRING "Supported build types." FORCE) + # Platform-specific compilation flags. if (WINDOWS) diff --git a/indra/cmake/Boost.cmake b/indra/cmake/Boost.cmake index 844d5dc490..0cfcc06d2f 100644 --- a/indra/cmake/Boost.cmake +++ b/indra/cmake/Boost.cmake @@ -7,78 +7,90 @@ set(Boost_FIND_REQUIRED ON) if (STANDALONE) include(FindBoost) - set(Boost_USE_MULTITHREADED ON) - find_package(Boost 1.51.0 COMPONENTS date_time filesystem program_options regex system thread wave context) + set(BOOST_FILESYSTEM_LIBRARY boost_filesystem-mt) + set(BOOST_PROGRAM_OPTIONS_LIBRARY boost_program_options-mt) + set(BOOST_REGEX_LIBRARY boost_regex-mt) + set(BOOST_SIGNALS_LIBRARY boost_signals-mt) else (STANDALONE) use_prebuilt_binary(boost) set(Boost_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include) - set(Boost_VERSION "1.60") + set(BOOST_VERSION "1.60") if (WINDOWS) - set(Boost_CONTEXT_LIBRARY + set(BOOST_CHRONO_LIBRARY + optimized libboost_chrono-mt + debug libboost_chrono-mt-gd) + set(BOOST_CONTEXT_LIBRARY optimized libboost_context-mt debug libboost_context-mt-gd) - set(Boost_FILESYSTEM_LIBRARY + set(BOOST_FILESYSTEM_LIBRARY optimized libboost_filesystem-mt debug libboost_filesystem-mt-gd) - set(Boost_PROGRAM_OPTIONS_LIBRARY + set(BOOST_PROGRAM_OPTIONS_LIBRARY optimized libboost_program_options-mt debug libboost_program_options-mt-gd) - set(Boost_REGEX_LIBRARY + set(BOOST_REGEX_LIBRARY optimized libboost_regex-mt debug libboost_regex-mt-gd) - set(Boost_SIGNALS_LIBRARY + set(BOOST_SIGNALS_LIBRARY optimized libboost_signals-mt debug libboost_signals-mt-gd) - set(Boost_SYSTEM_LIBRARY + set(BOOST_SYSTEM_LIBRARY optimized libboost_system-mt debug libboost_system-mt-gd) - set(Boost_THREAD_LIBRARY + set(BOOST_THREAD_LIBRARY optimized libboost_thread-mt debug libboost_thread-mt-gd) elseif (LINUX) - set(Boost_CONTEXT_LIBRARY + set(BOOST_CHRONO_LIBRARY + optimized boost_chrono-mt + debug boost_chrono-mt-d) + set(BOOST_CONTEXT_LIBRARY optimized boost_context-mt debug boost_context-mt-d) - set(Boost_FILESYSTEM_LIBRARY + set(BOOST_FILESYSTEM_LIBRARY optimized boost_filesystem-mt debug boost_filesystem-mt-d) - set(Boost_PROGRAM_OPTIONS_LIBRARY + set(BOOST_PROGRAM_OPTIONS_LIBRARY optimized boost_program_options-mt debug boost_program_options-mt-d) - set(Boost_REGEX_LIBRARY + set(BOOST_REGEX_LIBRARY optimized boost_regex-mt debug boost_regex-mt-d) - set(Boost_SIGNALS_LIBRARY + set(BOOST_SIGNALS_LIBRARY optimized boost_signals-mt debug boost_signals-mt-d) - set(Boost_SYSTEM_LIBRARY + set(BOOST_SYSTEM_LIBRARY optimized boost_system-mt debug boost_system-mt-d) - set(Boost_THREAD_LIBRARY + set(BOOST_THREAD_LIBRARY optimized boost_thread-mt debug boost_thread-mt-d) elseif (DARWIN) - set(Boost_CONTEXT_LIBRARY + set(BOOST_CHRONO_LIBRARY + optimized boost_chrono-mt + debug boost_chrono-mt-d) + set(BOOST_CONTEXT_LIBRARY optimized boost_context-mt debug boost_context-mt-d) - set(Boost_FILESYSTEM_LIBRARY + set(BOOST_FILESYSTEM_LIBRARY optimized boost_filesystem-mt debug boost_filesystem-mt-d) - set(Boost_PROGRAM_OPTIONS_LIBRARY + set(BOOST_PROGRAM_OPTIONS_LIBRARY optimized boost_program_options-mt debug boost_program_options-mt-d) - set(Boost_REGEX_LIBRARY + set(BOOST_REGEX_LIBRARY optimized boost_regex-mt debug boost_regex-mt-d) - set(Boost_SIGNALS_LIBRARY + set(BOOST_SIGNALS_LIBRARY optimized boost_signals-mt debug boost_signals-mt-d) - set(Boost_SYSTEM_LIBRARY + set(BOOST_SYSTEM_LIBRARY optimized boost_system-mt debug boost_system-mt-d) - set(Boost_THREAD_LIBRARY + set(BOOST_THREAD_LIBRARY optimized boost_thread-mt debug boost_thread-mt-d) endif (WINDOWS) endif (STANDALONE) + diff --git a/indra/cmake/CARes.cmake b/indra/cmake/CARes.cmake deleted file mode 100644 index 02fad1f550..0000000000 --- a/indra/cmake/CARes.cmake +++ /dev/null @@ -1,24 +0,0 @@ -# -*- cmake -*- -include(Linking) -include(Prebuilt) - -set(CARES_FIND_QUIETLY ON) -set(CARES_FIND_REQUIRED ON) - -if (STANDALONE) - include(FindCARes) -else (STANDALONE) - use_prebuilt_binary(ares) - if (WINDOWS) - add_definitions("-DCARES_STATICLIB") - set(CARES_LIBRARIES areslib) - elseif (DARWIN) - set(CARES_LIBRARIES - debug libcares.a - optimized libcares.a - ) - else (WINDOWS) - set(CARES_LIBRARIES cares) - endif (WINDOWS) - set(CARES_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include/ares) -endif (STANDALONE) diff --git a/indra/cmake/CMakeLists.txt b/indra/cmake/CMakeLists.txt index 4b2c896fdd..be1beb46b2 100644 --- a/indra/cmake/CMakeLists.txt +++ b/indra/cmake/CMakeLists.txt @@ -12,14 +12,12 @@ set(cmake_SOURCE_FILES Audio.cmake Boost.cmake BuildVersion.cmake - CARes.cmake CEFPlugin.cmake CMakeCopyIfDifferent.cmake CURL.cmake Colladadom.cmake ConfigurePkgConfig.cmake Copy3rdPartyLibs.cmake - Cwdebug.cmake DBusGlib.cmake DeploySharedLibs.cmake EXPAT.cmake @@ -27,7 +25,6 @@ set(cmake_SOURCE_FILES FMODSTUDIO.cmake FindAPR.cmake FindAutobuild.cmake - FindCARes.cmake FindColladadom.cmake FindGLOD.cmake FindGoogleBreakpad.cmake diff --git a/indra/cmake/Cwdebug.cmake b/indra/cmake/Cwdebug.cmake deleted file mode 100644 index d469386e1e..0000000000 --- a/indra/cmake/Cwdebug.cmake +++ /dev/null @@ -1,18 +0,0 @@ -include_directories (${CMAKE_SOURCE_DIR}/cwdebug) - -set(cwdebug_SOURCE_FILES - ${CMAKE_SOURCE_DIR}/cwdebug/debug.cc - ) - -set(cwdebug_HEADER_FILES - ${CMAKE_SOURCE_DIR}/cwdebug/cwdebug.h - ${CMAKE_SOURCE_DIR}/cwdebug/sys.h - ${CMAKE_SOURCE_DIR}/cwdebug/debug.h - ${CMAKE_SOURCE_DIR}/cwdebug/debug_ostream_operators.h - ) - -set_source_files_properties(${cwdebug_HEADER_FILES} - PROPERTIES HEADER_FILE_ONLY TRUE) - -list(APPEND cwdebug_SOURCE_FILES ${cwdebug_HEADER_FILES}) - diff --git a/indra/cmake/FindCARes.cmake b/indra/cmake/FindCARes.cmake deleted file mode 100644 index 1ed5b32913..0000000000 --- a/indra/cmake/FindCARes.cmake +++ /dev/null @@ -1,48 +0,0 @@ -# -*- cmake -*- - -# - Find c-ares -# Find the c-ares includes and library -# This module defines -# CARES_INCLUDE_DIR, where to find ares.h, etc. -# CARES_LIBRARIES, the libraries needed to use c-ares. -# CARES_FOUND, If false, do not try to use c-ares. -# also defined, but not for general use are -# CARES_LIBRARY, where to find the c-ares library. - -FIND_PATH(CARES_INCLUDE_DIR ares.h -/usr/local/include -/usr/include -) - -SET(CARES_NAMES ${CARES_NAMES} cares) -FIND_LIBRARY(CARES_LIBRARY - NAMES ${CARES_NAMES} - PATHS /usr/lib /usr/local/lib - ) - -IF (CARES_LIBRARY AND CARES_INCLUDE_DIR) - SET(CARES_LIBRARIES ${CARES_LIBRARY}) - SET(CARES_FOUND "YES") -ELSE (CARES_LIBRARY AND CARES_INCLUDE_DIR) - SET(CARES_FOUND "NO") -ENDIF (CARES_LIBRARY AND CARES_INCLUDE_DIR) - - -IF (CARES_FOUND) - IF (NOT CARES_FIND_QUIETLY) - MESSAGE(STATUS "Found c-ares: ${CARES_LIBRARIES}") - ENDIF (NOT CARES_FIND_QUIETLY) -ELSE (CARES_FOUND) - IF (CARES_FIND_REQUIRED) - MESSAGE(FATAL_ERROR "Could not find c-ares library") - ENDIF (CARES_FIND_REQUIRED) -ENDIF (CARES_FOUND) - -# Deprecated declarations. -SET (NATIVE_CARES_INCLUDE_PATH ${CARES_INCLUDE_DIR} ) -GET_FILENAME_COMPONENT (NATIVE_CARES_LIB_PATH ${CARES_LIBRARY} PATH) - -MARK_AS_ADVANCED( - CARES_LIBRARY - CARES_INCLUDE_DIR - ) diff --git a/indra/cmake/LLAddBuildTest.cmake b/indra/cmake/LLAddBuildTest.cmake index 290db9f221..767fab2cf5 100644 --- a/indra/cmake/LLAddBuildTest.cmake +++ b/indra/cmake/LLAddBuildTest.cmake @@ -3,7 +3,6 @@ INCLUDE(APR) INCLUDE(LLMath) INCLUDE(Tut) -INCLUDE(Cwdebug) MACRO(ADD_BUILD_TEST_NO_COMMON name parent) # MESSAGE("${CMAKE_CURRENT_SOURCE_DIR}/tests/${name}_test.cpp") diff --git a/indra/cmake/LLAppearance.cmake b/indra/cmake/LLAppearance.cmake index ba0274a657..a928175cd0 100644 --- a/indra/cmake/LLAppearance.cmake +++ b/indra/cmake/LLAppearance.cmake @@ -1,11 +1,24 @@ # -*- cmake -*- include(Variables) +include(Boost) +include(LLMessage) +include(LLCoreHttp) set(LLAPPEARANCE_INCLUDE_DIRS ${LIBS_OPEN_DIR}/llappearance ) -set(LLAPPEARANCE_LIBRARIES llappearance) +if (BUILD_HEADLESS) + set(LLAPPEARANCE_HEADLESS_LIBRARIES + llappearanceheadless + ) +endif (BUILD_HEADLESS) + +set(LLAPPEARANCE_LIBRARIES llappearance + llmessage + llcorehttp + ) + diff --git a/indra/cmake/LLAudio.cmake b/indra/cmake/LLAudio.cmake index 1f5fd63ed9..88369127f9 100644 --- a/indra/cmake/LLAudio.cmake +++ b/indra/cmake/LLAudio.cmake @@ -8,5 +8,5 @@ set(LLAUDIO_INCLUDE_DIRS ) add_definitions(-DOV_EXCLUDE_STATIC_CALLBACKS) - -set(LLAUDIO_LIBRARIES llaudio ${OPENAL_LIBRARIES}) +# be exhaustive here +set(LLAUDIO_LIBRARIES llaudio ${VORBISFILE_LIBRARIES} ${VORBIS_LIBRARIES} ${VORBISENC_LIBRARIES} ${OGG_LIBRARIES} ${OPENAL_LIBRARIES}) diff --git a/indra/cmake/LLCommon.cmake b/indra/cmake/LLCommon.cmake index 6cc3254950..fb74b741aa 100644 --- a/indra/cmake/LLCommon.cmake +++ b/indra/cmake/LLCommon.cmake @@ -5,28 +5,17 @@ include(Boost) include(EXPAT) include(ZLIB) -if (DARWIN) - include(CMakeFindFrameworks) - find_library(CORESERVICES_LIBRARY CoreServices) -endif (DARWIN) - - set(LLCOMMON_INCLUDE_DIRS - ${LIBS_OPEN_DIR}/cwdebug ${LIBS_OPEN_DIR}/llcommon ${APRUTIL_INCLUDE_DIR} ${APR_INCLUDE_DIR} + ) +set(LLCOMMON_SYSTEM_INCLUDE_DIRS ${Boost_INCLUDE_DIRS} ) -if (LINUX) - # In order to support using ld.gold on linux, we need to explicitely - # specify all libraries that llcommon uses. - # llcommon uses `clock_gettime' which is provided by librt on linux. - set(LLCOMMON_LIBRARIES llcommon rt) -else (LINUX) - set(LLCOMMON_LIBRARIES llcommon) -endif (LINUX) +set(LLCOMMON_LIBRARIES llcommon) + set(LLCOMMON_LINK_SHARED OFF CACHE BOOL "Build the llcommon target as a shared library.") if(LLCOMMON_LINK_SHARED) diff --git a/indra/cmake/LLCoreHttp.cmake b/indra/cmake/LLCoreHttp.cmake index 379ae207de..3a9282a3fc 100644 --- a/indra/cmake/LLCoreHttp.cmake +++ b/indra/cmake/LLCoreHttp.cmake @@ -11,7 +11,4 @@ set(LLCOREHTTP_INCLUDE_DIRS ${BOOST_INCLUDE_DIRS} ) -set(LLCOREHTTP_LIBRARIES llcorehttp - ${BOOST_COROUTINE_LIBRARY} - ${BOOST_CONTEXT_LIBRARY} - ${BOOST_SYSTEM_LIBRARY}) +set(LLCOREHTTP_LIBRARIES llcorehttp) diff --git a/indra/cmake/LLMessage.cmake b/indra/cmake/LLMessage.cmake index 0143d04fd7..7be53ec0ec 100644 --- a/indra/cmake/LLMessage.cmake +++ b/indra/cmake/LLMessage.cmake @@ -1,13 +1,11 @@ # -*- cmake -*- -include(CARes) include(CURL) include(OpenSSL) include(XmlRpcEpi) set(LLMESSAGE_INCLUDE_DIRS ${LIBS_OPEN_DIR}/llmessage - ${CARES_INCLUDE_DIRS} ${CURL_INCLUDE_DIRS} ${OPENSSL_INCLUDE_DIRS} ) diff --git a/indra/cmake/LLPlugin.cmake b/indra/cmake/LLPlugin.cmake index 399cb332dd..9722f16c3c 100644 --- a/indra/cmake/LLPlugin.cmake +++ b/indra/cmake/LLPlugin.cmake @@ -5,10 +5,4 @@ set(LLPLUGIN_INCLUDE_DIRS ${LIBS_OPEN_DIR}/llplugin ) -if (LINUX) - # In order to support using ld.gold on linux, we need to explicitely - # specify all libraries that llplugin uses. - set(LLPLUGIN_LIBRARIES llplugin pthread) -else (LINUX) - set(LLPLUGIN_LIBRARIES llplugin) -endif (LINUX) +set(LLPLUGIN_LIBRARIES llplugin) diff --git a/indra/cmake/LLPrimitive.cmake b/indra/cmake/LLPrimitive.cmake index ee465dc8bd..f9c81c7e15 100644 --- a/indra/cmake/LLPrimitive.cmake +++ b/indra/cmake/LLPrimitive.cmake @@ -18,13 +18,11 @@ if (WINDOWS) llprimitive ${COLLADADOM_LIBRARIES} libxml2_a - ${BOOST_SYSTEM_LIBRARIES} ) else (WINDOWS) set(LLPRIMITIVE_LIBRARIES llprimitive ${COLLADADOM_LIBRARIES} - ${BOOST_SYSTEM_LIBRARIES} minizip xml2 ) diff --git a/indra/cmake/LLVFS.cmake b/indra/cmake/LLVFS.cmake index a719764659..0fe87cdea6 100644 --- a/indra/cmake/LLVFS.cmake +++ b/indra/cmake/LLVFS.cmake @@ -1,12 +1,7 @@ # -*- cmake -*- -include(Boost) - set(LLVFS_INCLUDE_DIRS ${LIBS_OPEN_DIR}/llvfs ) -set(LLVFS_LIBRARIES - llvfs - ${Boost_REGEX_LIBRARY} - ) +set(LLVFS_LIBRARIES llvfs) diff --git a/indra/cmake/LLXML.cmake b/indra/cmake/LLXML.cmake index 64dfdb604f..b093c76297 100644 --- a/indra/cmake/LLXML.cmake +++ b/indra/cmake/LLXML.cmake @@ -5,8 +5,10 @@ include(EXPAT) set(LLXML_INCLUDE_DIRS ${LIBS_OPEN_DIR}/llxml - ${Boost_INCLUDE_DIRS} ${EXPAT_INCLUDE_DIRS} ) +set(LLXML_SYSTEM_INCLUDE_DIRS + ${Boost_INCLUDE_DIRS} + ) set(LLXML_LIBRARIES llxml) diff --git a/indra/cmake/Variables.cmake b/indra/cmake/Variables.cmake index 8c4ca493ec..f4a457aa5c 100644 --- a/indra/cmake/Variables.cmake +++ b/indra/cmake/Variables.cmake @@ -142,43 +142,30 @@ endif (${CMAKE_SYSTEM_NAME} MATCHES "Linux") if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") set(DARWIN 1) - execute_process( - COMMAND sh -c "xcodebuild -version | grep Xcode | cut -d ' ' -f2 | cut -d'.' -f1-2" - OUTPUT_VARIABLE XCODE_VERSION ) - string(REGEX REPLACE "(\r?\n)+$" "" XCODE_VERSION "${XCODE_VERSION}") - - # Hardcode SDK we build against until we can test and allow newer ones - # as autodetected in the code above - set(CMAKE_OSX_DEPLOYMENT_TARGET 10.6) - set(CMAKE_OSX_SYSROOT macosx10.6) - - # Support for Unix Makefiles generator - if (CMAKE_GENERATOR STREQUAL "Unix Makefiles") - execute_process(COMMAND xcodebuild -version -sdk "${CMAKE_OSX_SYSROOT}" Path | head -n 1 OUTPUT_VARIABLE CMAKE_OSX_SYSROOT) - string(REGEX REPLACE "(\r?\n)+$" "" CMAKE_OSX_SYSROOT "${CMAKE_OSX_SYSROOT}") - endif (CMAKE_GENERATOR STREQUAL "Unix Makefiles") - - # LLVM-GCC has been removed in Xcode5 - if (XCODE_VERSION GREATER 4.9) + # now we only support Xcode 7.0 using 10.11 (El Capitan), minimum OS 10.7 (Lion) + set(XCODE_VERSION 7.0) + set(CMAKE_OSX_DEPLOYMENT_TARGET 10.7) + set(CMAKE_OSX_SYSROOT macosx10.11) + set(CMAKE_XCODE_ATTRIBUTE_GCC_VERSION "com.apple.compilers.llvm.clang.1_0") - else (XCODE_VERSION GREATER 4.9) - set(CMAKE_XCODE_ATTRIBUTE_GCC_VERSION "com.apple.compilers.llvmgcc42") - endif (XCODE_VERSION GREATER 4.9) + set(CMAKE_XCODE_ATTRIBUTE_GCC_OPTIMIZATION_LEVEL 3) + set(CMAKE_XCODE_ATTRIBUTE_GCC_STRICT_ALIASING NO) + set(CMAKE_XCODE_ATTRIBUTE_GCC_FAST_MATH NO) + set(CMAKE_XCODE_ATTRIBUTE_CLANG_X86_VECTOR_INSTRUCTIONS ssse3) + set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libstdc++") set(CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT dwarf-with-dsym) - message(STATUS "Xcode version: ${XCODE_VERSION}") - message(STATUS "OSX sysroot: ${CMAKE_OSX_SYSROOT}") - message(STATUS "OSX deployment target: ${CMAKE_OSX_DEPLOYMENT_TARGET}") - - # Build only for i386 by default, system default on MacOSX 10.6 is x86_64 - set(CMAKE_OSX_ARCHITECTURES i386) - set(ARCH i386) - set(WORD_SIZE 32) - set(AUTOBUILD_PLATFORM_NAME "darwin") + # Build only for i386 by default, system default on MacOSX 10.6+ is x86_64 + if (NOT CMAKE_OSX_ARCHITECTURES) + set(CMAKE_OSX_ARCHITECTURES "i386") + endif (NOT CMAKE_OSX_ARCHITECTURES) + set(ARCH ${CMAKE_OSX_ARCHITECTURES}) set(LL_ARCH ${ARCH}_darwin) set(LL_ARCH_DIR universal-darwin) + set(WORD_SIZE 32) + set(AUTOBUILD_PLATFORM_NAME "darwin") endif (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") # Default deploy grid @@ -190,7 +177,7 @@ set(ENABLE_SIGNING OFF CACHE BOOL "Enable signing the viewer") set(SIGNING_IDENTITY "" CACHE STRING "Specifies the signing identity to use, if necessary.") set(VERSION_BUILD "0" CACHE STRING "Revision number passed in from the outside") -set(STANDALONE OFF CACHE BOOL "Do not use Linden-supplied prebuilt libraries.") +set(STANDALONE OFF CACHE BOOL "Use libraries from your system rather than Linden-supplied prebuilt libraries.") set(USE_PRECOMPILED_HEADERS ON CACHE BOOL "Enable use of precompiled header directives where supported.") diff --git a/indra/llappearance/CMakeLists.txt b/indra/llappearance/CMakeLists.txt index 51db4c9277..74b5f188ff 100644 --- a/indra/llappearance/CMakeLists.txt +++ b/indra/llappearance/CMakeLists.txt @@ -9,6 +9,7 @@ include(LLImage) include(LLInventory) include(LLMath) include(LLMessage) +include(LLCoreHttp) include(LLRender) include(LLVFS) include(LLWindow) @@ -85,5 +86,8 @@ target_link_libraries(llappearance ${LLVFS_LIBRARIES} ${LLMATH_LIBRARIES} ${LLXML_LIBRARIES} + ${LLMATH_LIBRARIES} + ${LLMESSAGE_LIBRARIES} + ${LLCOREHTTP_LIBRARIES} ${LLCOMMON_LIBRARIES} ) diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index 205451e0eb..ee6acf7d61 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -2,13 +2,12 @@ project(llcommon) -include(Cwdebug) include(00-Common) include(LLCommon) -include(APR) include(Linking) include(Boost) include(LLSharedLibs) +include(JsonCpp) include(GoogleBreakpad) include(Copy3rdPartyLibs) include(ZLIB) @@ -16,6 +15,7 @@ include(ZLIB) include_directories( ${EXPAT_INCLUDE_DIRS} ${LLCOMMON_INCLUDE_DIRS} + ${JSONCPP_INCLUDE_DIR} ${ZLIB_INCLUDE_DIRS} ${BREAKPAD_INCLUDE_DIRECTORIES} ) @@ -267,8 +267,6 @@ set(llcommon_HEADER_FILES set_source_files_properties(${llcommon_HEADER_FILES} PROPERTIES HEADER_FILE_ONLY TRUE) -list(APPEND llcommon_SOURCE_FILES ${cwdebug_SOURCE_FILES}) - list(APPEND llcommon_SOURCE_FILES ${llcommon_HEADER_FILES}) if(NOT WORD_SIZE EQUAL 32) @@ -276,7 +274,6 @@ if(NOT WORD_SIZE EQUAL 32) add_definitions(-fPIC) endif(NOT WINDOWS) endif(NOT WORD_SIZE EQUAL 32) - if(LLCOMMON_LINK_SHARED) add_library (llcommon SHARED ${llcommon_SOURCE_FILES}) if(WINDOWS) @@ -294,23 +291,21 @@ target_link_libraries( ${APRUTIL_LIBRARIES} ${APR_LIBRARIES} ${EXPAT_LIBRARIES} + ${JSONCPP_LIBRARIES} ${ZLIB_LIBRARIES} ${WINDOWS_LIBRARIES} - ${Boost_CONTEXT_LIBRARY} - ${Boost_REGEX_LIBRARY} - ${Boost_THREAD_LIBRARY} - ${Boost_SYSTEM_LIBRARY} - ${CORESERVICES_LIBRARY} + ${BOOST_CONTEXT_LIBRARY} + ${BOOST_PROGRAM_OPTIONS_LIBRARY} + ${BOOST_REGEX_LIBRARY} + ${BOOST_THREAD_LIBRARY} + ${BOOST_CHRONO_LIBRARY} + ${BOOST_SYSTEM_LIBRARY} ) if (DARWIN) - # Don't embed a full path in the library's install name - set_target_properties( - llcommon - PROPERTIES - BUILD_WITH_INSTALL_RPATH 1 - INSTALL_NAME_DIR "@executable_path/../Resources" - ) + include(CMakeFindFrameworks) + find_library(CARBON_LIBRARY Carbon) + target_link_libraries(llcommon ${CARBON_LIBRARY}) endif (DARWIN) add_dependencies(llcommon stage_third_party_libs) diff --git a/indra/llcommon/aisyncclient.cpp b/indra/llcommon/aisyncclient.cpp index c62d88efb6..400b537ecc 100644 --- a/indra/llcommon/aisyncclient.cpp +++ b/indra/llcommon/aisyncclient.cpp @@ -81,11 +81,9 @@ * by searching through it for the pointer to the server. */ -#include "sys.h" #include "aisyncclient.h" #include #include -#include "debug.h" bool operator==(AISyncKey const& key1, AISyncKey const& key2) { diff --git a/indra/llcommon/llapp.h b/indra/llcommon/llapp.h index fd3b092963..245cfa9c44 100644 --- a/indra/llcommon/llapp.h +++ b/indra/llcommon/llapp.h @@ -32,6 +32,10 @@ #include "llsd.h" #include "lloptioninterface.h" +#if !LL_WINDOWS +#include "llatomic.h" +#endif + // Forward declarations class LLErrorThread; class LLLiveFile; diff --git a/indra/llcommon/llerror.h b/indra/llcommon/llerror.h index 8b5da97a52..144d45bfa4 100644 --- a/indra/llcommon/llerror.h +++ b/indra/llcommon/llerror.h @@ -72,7 +72,7 @@ const int LL_ERR_NOERR = 0; #endif // !_DEBUG -static const std::string liru_assert_strip(const std::string& file) { return file.substr(1+file.substr(0, file.find_last_of("/\\")).find_last_of("/\\")); } //return foo/bar.cpp or perhaps foo\bar.cpp +inline const std::string liru_assert_strip(const std::string& file) { return file.substr(1+file.substr(0, file.find_last_of("/\\")).find_last_of("/\\")); } //return foo/bar.cpp or perhaps foo\bar.cpp #define llassert_always_msg(func, msg) if (LL_UNLIKELY(!(func))) LL_ERRS() << "ASSERT (" << msg << ")\nfile:" << liru_assert_strip(__FILE__) << " line:" << std::dec << __LINE__ << LL_ENDL diff --git a/indra/llcommon/llfasttimer.h b/indra/llcommon/llfasttimer.h index b699f7e66f..37fba527f1 100644 --- a/indra/llcommon/llfasttimer.h +++ b/indra/llcommon/llfasttimer.h @@ -222,7 +222,7 @@ class BlockTimer BlockTimer(const BlockTimer& other) {}; private: - U64 mStartTime; + U64 mStartTime = getCPUClockCount64(); BlockTimerStackRecord mParentTimerData; public: diff --git a/indra/llcommon/llframetimer.h b/indra/llcommon/llframetimer.h index b37622e6c3..ad26e93e8a 100644 --- a/indra/llcommon/llframetimer.h +++ b/indra/llcommon/llframetimer.h @@ -99,7 +99,7 @@ class LL_COMMON_API LLFrameTimer F32 getElapsedTimeF32() const { return mStarted ? (F32)(sFrameTime - mStartTime) : (F32)mStartTime; } BOOL getStarted() const { return mStarted; } // - F64 getStartTime() const { llassert(!mPaused); return mStartTime; } + F64 getStartTime() const { return mStartTime; } // // return the seconds since epoch when this timer will expire. diff --git a/indra/llcommon/llsdjson.cpp b/indra/llcommon/llsdjson.cpp index 8caaaee534..f0e4a2c3fe 100644 --- a/indra/llcommon/llsdjson.cpp +++ b/indra/llcommon/llsdjson.cpp @@ -70,7 +70,7 @@ LLSD LlsdFromJson(const Json::Value &val) result = LLSD::emptyMap(); for (Json::ValueConstIterator it = val.begin(); it != val.end(); ++it) { - result[it.memberName()] = LlsdFromJson((*it)); + result[it.name()] = LlsdFromJson((*it)); } break; } diff --git a/indra/llcorehttp/CMakeLists.txt b/indra/llcorehttp/CMakeLists.txt index 71cf209ff4..9b13bd616b 100644 --- a/indra/llcorehttp/CMakeLists.txt +++ b/indra/llcorehttp/CMakeLists.txt @@ -91,9 +91,7 @@ target_link_libraries( ${CURL_LIBRARIES} ${OPENSSL_LIBRARIES} ${CRYPTO_LIBRARIES} - ${BOOST_THREAD_LIBRARY} ${BOOST_CHRONO_LIBRARY} - ${BOOST_SYSTEM_LIBRARY} ) # tests @@ -129,9 +127,7 @@ if (LL_TESTS) ${CURL_LIBRARIES} ${OPENSSL_LIBRARIES} ${CRYPTO_LIBRARIES} - ${BOOST_THREAD_LIBRARY} ${BOOST_CHRONO_LIBRARY} - ${BOOST_SYSTEM_LIBRARY} ) # If http_proxy is in the current environment (e.g. to fetch s3-proxy @@ -160,9 +156,7 @@ if (LL_TESTS) ${CURL_LIBRARIES} ${OPENSSL_LIBRARIES} ${CRYPTO_LIBRARIES} - ${BOOST_THREAD_LIBRARY} ${BOOST_CHRONO_LIBRARY} - ${BOOST_SYSTEM_LIBRARY} ) add_executable(http_texture_load diff --git a/indra/llimage/CMakeLists.txt b/indra/llimage/CMakeLists.txt index e2385da50b..fb80324d50 100644 --- a/indra/llimage/CMakeLists.txt +++ b/indra/llimage/CMakeLists.txt @@ -14,6 +14,7 @@ include(LLAddBuildTest) include_directories( ${LLCOMMON_INCLUDE_DIRS} + ${LLCOMMON_SYSTEM_INCLUDE_DIRS} ${LLMATH_INCLUDE_DIRS} ${LLVFS_INCLUDE_DIRS} ${JPEG_INCLUDE_DIRS} diff --git a/indra/llimagej2coj/CMakeLists.txt b/indra/llimagej2coj/CMakeLists.txt index af7d356011..47f2ce3e9c 100644 --- a/indra/llimagej2coj/CMakeLists.txt +++ b/indra/llimagej2coj/CMakeLists.txt @@ -25,7 +25,6 @@ set(llimagej2coj_HEADER_FILES llimagej2coj.h ) - set_source_files_properties(${llimagej2coj_HEADER_FILES} PROPERTIES HEADER_FILE_ONLY TRUE) diff --git a/indra/llinventory/CMakeLists.txt b/indra/llinventory/CMakeLists.txt index 028117151b..920ccbd22f 100644 --- a/indra/llinventory/CMakeLists.txt +++ b/indra/llinventory/CMakeLists.txt @@ -4,8 +4,10 @@ project(llinventory) include(00-Common) include(LLCommon) +include(LLCoreHttp) include(LLMath) include(LLMessage) +include(LLVFS) include(LLXML) include_directories( diff --git a/indra/llmath/CMakeLists.txt b/indra/llmath/CMakeLists.txt index ff174112aa..bd44d83e7d 100644 --- a/indra/llmath/CMakeLists.txt +++ b/indra/llmath/CMakeLists.txt @@ -7,6 +7,7 @@ include(LLCommon) include_directories( ${LLCOMMON_INCLUDE_DIRS} + ${LLCOMMON_SYSTEM_INCLUDE_DIRS} ) set(llmath_SOURCE_FILES diff --git a/indra/llmessage/CMakeLists.txt b/indra/llmessage/CMakeLists.txt index d9146b6f3b..92608d8b91 100644 --- a/indra/llmessage/CMakeLists.txt +++ b/indra/llmessage/CMakeLists.txt @@ -3,12 +3,18 @@ project(llmessage) include(00-Common) +include(LLAddBuildTest) include(LLCommon) include(LLCoreHttp) include(LLMath) include(LLMessage) include(LLVFS) include(LLXML) +include(LLAddBuildTest) +include(Python) +include(Tut) +include(Python) +include(JsonCpp) include_directories (${CMAKE_CURRENT_SOURCE_DIR}) @@ -19,6 +25,7 @@ include_directories( ${LLMESSAGE_INCLUDE_DIRS} ${LLVFS_INCLUDE_DIRS} ${LLXML_INCLUDE_DIRS} + ${JSONCPP_INCLUDE_DIR} ) set(llmessage_SOURCE_FILES @@ -193,53 +200,76 @@ list(APPEND llmessage_SOURCE_FILES ${llmessage_HEADER_FILES}) add_library (llmessage ${llmessage_SOURCE_FILES}) +if (LINUX) target_link_libraries( llmessage ${CURL_LIBRARIES} - ${CARES_LIBRARIES} + ${LLCOMMON_LIBRARIES} + ${LLVFS_LIBRARIES} + ${LLMATH_LIBRARIES} + ${JSONCPP_LIBRARIES} ${OPENSSL_LIBRARIES} ${CRYPTO_LIBRARIES} ${XMLRPCEPI_LIBRARIES} ${LLCOREHTTP_LIBRARIES} + rt ) +else (LINUX) +target_link_libraries( + llmessage + ${CURL_LIBRARIES} + ${LLCOMMON_LIBRARIES} + ${LLVFS_LIBRARIES} + ${LLMATH_LIBRARIES} + ${JSONCPP_LIBRARIES} + ${OPENSSL_LIBRARIES} + ${CRYPTO_LIBRARIES} + ${XMLRPCEPI_LIBRARIES} + ${LLCOREHTTP_LIBRARIES} + ) +endif(LINUX) # tests if (LL_TESTS) - include(GoogleMock) - include(LLAddBuildTest) - include(Python) - include(Tut) - SET(llmessage_TEST_SOURCE_FILES - llmime.cpp llnamevalue.cpp lltrustedmessageservice.cpp lltemplatemessagedispatcher.cpp ) LL_ADD_PROJECT_UNIT_TESTS(llmessage "${llmessage_TEST_SOURCE_FILES}") + # set(TEST_DEBUG on) + +if (LINUX) set(test_libs - ${LLMESSAGE_LIBRARIES} ${WINDOWS_LIBRARIES} ${LLVFS_LIBRARIES} ${LLMATH_LIBRARIES} ${CURL_LIBRARIES} ${LLCOMMON_LIBRARIES} + ${LLMESSAGE_LIBRARIES} ${LLCOREHTTP_LIBRARIES} + ${JSONCPP_LIBRARIES} + rt ${GOOGLEMOCK_LIBRARIES} ${LLXML_LIBRARIES} ) - - LL_ADD_INTEGRATION_TEST( - llsdmessage - "llsdmessage.cpp" - "${test_libs}" - ${PYTHON_EXECUTABLE} - "${CMAKE_CURRENT_SOURCE_DIR}/tests/test_llsdmessage_peer.py" +else (LINUX) + set(test_libs + ${WINDOWS_LIBRARIES} + ${LLVFS_LIBRARIES} + ${LLMATH_LIBRARIES} + ${CURL_LIBRARIES} + ${LLCOMMON_LIBRARIES} + ${LLMESSAGE_LIBRARIES} + ${LLCOREHTTP_LIBRARIES} + ${JSONCPP_LIBRARIES} + ${LLXML_LIBRARIES} ) +endif(LINUX) - LL_ADD_INTEGRATION_TEST(llavatarnamecache "" "${test_libs}") + #LL_ADD_INTEGRATION_TEST(llavatarnamecache "" "${test_libs}") LL_ADD_INTEGRATION_TEST(llhost "" "${test_libs}") LL_ADD_INTEGRATION_TEST(llpartdata "" "${test_libs}") LL_ADD_INTEGRATION_TEST(llxfer_file "" "${test_libs}") diff --git a/indra/llplugin/CMakeLists.txt b/indra/llplugin/CMakeLists.txt index 7dba8de082..89c59695a1 100644 --- a/indra/llplugin/CMakeLists.txt +++ b/indra/llplugin/CMakeLists.txt @@ -3,16 +3,28 @@ project(llplugin) include(00-Common) +include(CURL) include(LLCommon) +include(LLImage) include(LLMath) include(LLMessage) include(LLRender) +include(LLXML) +include(LLWindow) +include(Boost) include_directories( ${LLCOMMON_INCLUDE_DIRS} + ${LLIMAGE_INCLUDE_DIRS} ${LLMATH_INCLUDE_DIRS} ${LLMESSAGE_INCLUDE_DIRS} ${LLRENDER_INCLUDE_DIRS} + ${LLXML_INCLUDE_DIRS} + ${LLWINDOW_INCLUDE_DIRS} + ) +include_directories(SYSTEM + ${LLCOMMON_SYSTEM_INCLUDE_DIRS} + ${LLXML_SYSTEM_INCLUDE_DIRS} ) set(llplugin_SOURCE_FILES @@ -45,19 +57,20 @@ set_source_files_properties(${llplugin_HEADER_FILES} PROPERTIES HEADER_FILE_ONLY TRUE) if(NOT WORD_SIZE EQUAL 32) - if(WINDOWS) - # add_definitions(/FIXED:NO) - else(WINDOWS) # not windows therefore gcc LINUX and DARWIN + if(NOT WINDOWS) add_definitions(-fPIC) - endif(WINDOWS) + endif(NOT WINDOWS) endif (NOT WORD_SIZE EQUAL 32) list(APPEND llplugin_SOURCE_FILES ${llplugin_HEADER_FILES}) add_library (llplugin ${llplugin_SOURCE_FILES}) -if(LINUX AND STANDALONE) +if(LINUX) + target_link_libraries(llplugin pthread) + if (STANDALONE) target_link_libraries (llplugin rt dl) -endif(LINUX AND STANDALONE) + endif(STANDALONE) +endif(LINUX) add_subdirectory(slplugin) diff --git a/indra/llprimitive/CMakeLists.txt b/indra/llprimitive/CMakeLists.txt index b688e746ee..430aa9c88c 100644 --- a/indra/llprimitive/CMakeLists.txt +++ b/indra/llprimitive/CMakeLists.txt @@ -3,12 +3,13 @@ project(llprimitive) include(00-Common) +include(Colladadom) include(LLCommon) include(LLMath) include(LLMessage) +include(LLCoreHttp) include(LLXML) include(LLPhysicsExtensions) -include(Colladadom) include(LLCharacter) include_directories( @@ -71,3 +72,14 @@ set_source_files_properties(${llprimitive_HEADER_FILES} list(APPEND llprimitive_SOURCE_FILES ${llprimitive_HEADER_FILES}) add_library (llprimitive ${llprimitive_SOURCE_FILES}) + +target_link_libraries(llprimitive + ${LLCOMMON_LIBRARIES} + ${LLMATH_LIBRARIES} + ${LLMESSAGE_LIBRARIES} + ${LLCOREHTTP_LIBRARIES} + ${LLXML_LIBRARIES} + ${LLPHYSICSEXTENSIONS_LIBRARIES} + ${LLCHARACTER_LIBRARIES} + ) + diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt index b031108143..f4a4077425 100644 --- a/indra/llui/CMakeLists.txt +++ b/indra/llui/CMakeLists.txt @@ -5,16 +5,21 @@ project(llui) include(00-Common) include(LLCommon) include(LLImage) +include(LLInventory) include(LLMath) include(LLMessage) +include(LLCoreHttp) include(LLRender) include(LLWindow) +include(LLCoreHttp) include(LLVFS) include(LLXML) include_directories( ${LLCOMMON_INCLUDE_DIRS} + ${LLCOREHTTP_INCLUDE_DIRS} ${LLIMAGE_INCLUDE_DIRS} + ${LLINVENTORY_INCLUDE_DIRS} ${LLMATH_INCLUDE_DIRS} ${LLMESSAGE_INCLUDE_DIRS} ${LLRENDER_INCLUDE_DIRS} @@ -22,6 +27,10 @@ include_directories( ${LLVFS_INCLUDE_DIRS} ${LLXML_INCLUDE_DIRS} ) +include_directories(SYSTEM + ${LLCOMMON_SYSTEM_INCLUDE_DIRS} + ${LLXML_SYSTEM_INCLUDE_DIRS} + ) set(llui_SOURCE_FILES aialert.cpp diff --git a/indra/llvfs/CMakeLists.txt b/indra/llvfs/CMakeLists.txt index d9c192c653..de69f4be9d 100644 --- a/indra/llvfs/CMakeLists.txt +++ b/indra/llvfs/CMakeLists.txt @@ -8,6 +8,7 @@ include(UnixInstall) include_directories( ${LLCOMMON_INCLUDE_DIRS} + ${LLCOMMON_SYSTEM_INCLUDE_DIRS} ) set(llvfs_SOURCE_FILES @@ -64,9 +65,14 @@ list(APPEND llvfs_SOURCE_FILES ${llvfs_HEADER_FILES}) add_library (llvfs ${llvfs_SOURCE_FILES}) +set(vfs_BOOST_LIBRARIES + ${BOOST_FILESYSTEM_LIBRARY} + ${BOOST_SYSTEM_LIBRARY} + ) + target_link_libraries(llvfs - ${Boost_FILESYSTEM_LIBRARY} - ${Boost_SYSTEM_LIBRARY} + ${LLCOMMON_LIBRARIES} + ${vfs_BOOST_LIBRARIES} ) if (DARWIN) diff --git a/indra/llwindow/CMakeLists.txt b/indra/llwindow/CMakeLists.txt index 2a9396526f..e566c86581 100644 --- a/indra/llwindow/CMakeLists.txt +++ b/indra/llwindow/CMakeLists.txt @@ -30,6 +30,10 @@ include_directories( ${LLXML_INCLUDE_DIRS} ${DIRECTX_INCLUDE_DIR} ) +include_directories(SYSTEM + ${LLCOMMON_SYSTEM_INCLUDE_DIRS} + ${LLXML_SYSTEM_INCLUDE_DIRS} + ) set(llwindow_SOURCE_FILES llkeyboard.cpp @@ -82,6 +86,18 @@ if (LINUX) llwindowsdl.h ) + if (BUILD_HEADLESS) + set(llwindowheadless_LINK_LIBRARIES + ${LLCOMMON_LIBRARIES} + ${LLIMAGE_LIBRARIES} + ${LLMATH_LIBRARIES} + ${LLRENDER_HEADLESS_LIBRARIES} + ${LLVFS_LIBRARIES} + ${LLWINDOW_HEADLESS_LIBRARIES} + ${LLXML_LIBRARIES} + fontconfig # For FCInit and other FC* functions. + ) + endif (BUILD_HEADLESS) endif (LINUX) @@ -90,11 +106,14 @@ if (DARWIN) llkeyboardmacosx.cpp llwindowmacosx.cpp llwindowmacosx-objc.mm + llopenglview-objc.mm ) list(APPEND llwindow_HEADER_FILES llkeyboardmacosx.h llwindowmacosx.h llwindowmacosx-objc.h + llopenglview-objc.h + llappdelegate-objc.h ) # We use a bunch of deprecated system APIs. @@ -138,9 +157,29 @@ endif (SOLARIS) set_source_files_properties(${llwindow_HEADER_FILES} PROPERTIES HEADER_FILE_ONLY TRUE) +if (BUILD_HEADLESS) + set(llwindowheadless_SOURCE_FILES + llwindowmesaheadless.cpp + llmousehandler.cpp + ) + set(llwindowheadless_HEADER_FILES + llwindowmesaheadless.h + llmousehandler.h + ) + add_library (llwindowheadless + ${llwindow_SOURCE_FILES} + ${llwindowheadless_SOURCE_FILES} + ) + set_property(TARGET llwindowheadless + PROPERTY COMPILE_DEFINITIONS LL_MESA=1 LL_MESA_HEADLESS=1 + ) + target_link_libraries (llwindowheadless ${llwindowheadless_LINK_LIBRARIES} dl) +endif (BUILD_HEADLESS) + if (llwindow_HEADER_FILES) list(APPEND llwindow_SOURCE_FILES ${llwindow_HEADER_FILES}) endif (llwindow_HEADER_FILES) + list(APPEND viewer_SOURCE_FILES ${viewer_HEADER_FILES}) add_library (llwindow @@ -148,4 +187,10 @@ endif (llwindow_HEADER_FILES) ${viewer_SOURCE_FILES} ) +if (SDL_FOUND) + set_property(TARGET llwindow + PROPERTY COMPILE_DEFINITIONS LL_SDL=1 + ) +endif (SDL_FOUND) + target_link_libraries (llwindow ${llwindow_LINK_LIBRARIES}) diff --git a/indra/llwindow/llappdelegate-objc.h b/indra/llwindow/llappdelegate-objc.h new file mode 100644 index 0000000000..faa5d3abb7 --- /dev/null +++ b/indra/llwindow/llappdelegate-objc.h @@ -0,0 +1,48 @@ +/** + * @file llappdelegate-objc.h + * @brief Class interface for the Mac version's application delegate. + * + * $LicenseInfo:firstyear=2000&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#import +#import "llopenglview-objc.h" + +@interface LLAppDelegate : NSObject { + LLNSWindow *window; + NSWindow *inputWindow; + LLNonInlineTextView *inputView; + NSTimer *frameTimer; + NSString *currentInputLanguage; +} + +@property (assign) IBOutlet LLNSWindow *window; +@property (assign) IBOutlet NSWindow *inputWindow; +@property (assign) IBOutlet LLNonInlineTextView *inputView; + +@property (retain) NSString *currentInputLanguage; + +- (void) mainLoop; +- (void) showInputWindow:(bool)show withEvent:(NSEvent*)textEvent; +- (void) languageUpdated; +- (bool) romanScript; +@end diff --git a/indra/llxml/CMakeLists.txt b/indra/llxml/CMakeLists.txt index b6846c2474..84c55376ec 100644 --- a/indra/llxml/CMakeLists.txt +++ b/indra/llxml/CMakeLists.txt @@ -5,11 +5,16 @@ project(llxml) include(00-Common) include(LLCommon) include(LLMath) +include(LLVFS) include(LLXML) include_directories( ${LLCOMMON_INCLUDE_DIRS} ${LLMATH_INCLUDE_DIRS} + ${LLVFS_INCLUDE_DIRS} + ) +include_directories( + ${LLCOMMON_SYSTEM_INCLUDE_DIRS} ) set(llxml_SOURCE_FILES @@ -35,8 +40,12 @@ set_source_files_properties(${llxml_HEADER_FILES} list(APPEND llxml_SOURCE_FILES ${llxml_HEADER_FILES}) add_library (llxml ${llxml_SOURCE_FILES}) - -target_link_libraries( - llxml +# Libraries on which this library depends, needed for Linux builds +# Sort by high-level to low-level +target_link_libraries( llxml + ${LLVFS_LIBRARIES} + ${LLMATH_LIBRARIES} + ${LLCOMMON_LIBRARIES} ${EXPAT_LIBRARIES} ) + diff --git a/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp b/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp index 352b63583e..624b8fe365 100644 --- a/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp +++ b/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp @@ -76,7 +76,7 @@ class MediaPluginGStreamer010 : public MediaPluginBase bool play(double rate); bool getTimePos(double &sec_out); - static const double MIN_LOOP_SEC = 1.0F; + static constexpr double MIN_LOOP_SEC = 1.0F; bool mIsLooping; @@ -798,10 +798,13 @@ MediaPluginGStreamer010::startup() // only do global GStreamer initialization once. if (!mDoneInit) { - g_thread_init(NULL); - +#if !GLIB_CHECK_VERSION(2, 36, 0) +#if !GLIB_CHECK_VERSION(2, 32, 0) + if (!g_thread_supported()) g_thread_init(NULL); +#endif // Init the glib type system - we need it. g_type_init(); +#endif // Get symbols! #if LL_DARWIN diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 0044f27fe4..ff5619b535 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -72,6 +72,11 @@ include_directories( ${CMAKE_CURRENT_SOURCE_DIR} ) +include_directories(SYSTEM + ${LLCOMMON_SYSTEM_INCLUDE_DIRS} + ${LLXML_SYSTEM_INCLUDE_DIRS} + ) + set(viewer_SOURCE_FILES NACLantispam.cpp aifile.cpp @@ -312,6 +317,7 @@ set(viewer_SOURCE_FILES llinventoryfunctions.cpp llinventoryicon.cpp llinventorymodel.cpp + llinventorymodelbackgroundfetch.cpp llinventoryobserver.cpp llinventorypanel.cpp lljoystickbutton.cpp @@ -841,6 +847,7 @@ set(viewer_HEADER_FILES llinventoryfunctions.h llinventoryicon.h llinventorymodel.h + llinventorymodelbackgroundfetch.h llinventoryobserver.h llinventorypanel.h lljoystickbutton.h @@ -1652,23 +1659,23 @@ target_link_libraries(${VIEWER_BINARY_NAME} ${NDOF_LIBRARY} ${NVAPI_LIBRARY} ${viewer_LIBRARIES} - ${Boost_CONTEXT_LIBRARY} - ${Boost_FILESYSTEM_LIBRARY} - ${Boost_PROGRAM_OPTIONS_LIBRARY} - ${Boost_REGEX_LIBRARY} - ${Boost_SYSTEM_LIBRARY} - ${Boost_DATE_TIME_LIBRARY} + ${BOOST_CONTEXT_LIBRARY} + ${BOOST_FILESYSTEM_LIBRARY} + ${BOOST_PROGRAM_OPTIONS_LIBRARY} + ${BOOST_REGEX_LIBRARY} + ${BOOST_SYSTEM_LIBRARY} + ${BOOST_DATE_TIME_LIBRARY} ${DBUSGLIB_LIBRARIES} ${OPENGL_LIBRARIES} ${FMOD_LIBRARY} # must come after LLAudio ${GLOD_LIBRARIES} - ${APRUTIL_LIBRARIES} ${OPENGL_LIBRARIES} ${JSONCPP_LIBRARIES} ${SDL_LIBRARY} ${SMARTHEAP_LIBRARY} ${UI_LIBRARIES} ${WINDOWS_LIBRARIES} + ${EXPAT_LIBRARIES} ${XMLRPCEPI_LIBRARIES} ${HUNSPELL_LIBRARY} ${LLPHYSICSEXTENSIONS_LIBRARIES} @@ -1732,7 +1739,7 @@ if (LINUX) COMMENT "Performing viewer_manifest copy" ) - add_dependencies(${VIEWER_BINARY_NAME} SLPlugin media_plugin_gstreamer010 basic_plugin_filepicker) + add_dependencies(${VIEWER_BINARY_NAME} SLPlugin media_plugin_gstreamer010) add_custom_target(copy_l_viewer_manifest ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/.${product}.copy_touched) if (PACKAGE) @@ -1789,7 +1796,7 @@ if (DARWIN) ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py ) - add_dependencies(${VIEWER_BINARY_NAME} SLPlugin media_plugin_quicktime media_plugin_webkit basic_plugin_filepicker) + add_dependencies(${VIEWER_BINARY_NAME} SLPlugin media_plugin_quicktime media_plugin_cef) if (PACKAGE) add_custom_target(llpackage ALL DEPENDS ${VIEWER_BINARY_NAME}) diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index e5b91c108c..c1aa7878a7 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -2031,8 +2031,10 @@ bool LLAppViewer::initLoggingPortable() return true; } -bool LLAppViewer::loadSettingsFromDirectory(settings_map_type const& settings_r, - std::string const& location_key, +typedef std::map settings_map_type; +settings_map_type gSettings; + +bool LLAppViewer::loadSettingsFromDirectory(const std::string& location_key, bool set_defaults) { // Find and vet the location key. @@ -2061,12 +2063,12 @@ bool LLAppViewer::loadSettingsFromDirectory(settings_map_type const& settings_r, for(LLSD::map_iterator itr = files.beginMap(); itr != files.endMap(); ++itr) { std::string const settings_group = (*itr).first; - settings_map_type::const_iterator const settings_group_iter = settings_r.find(settings_group); + settings_map_type::const_iterator const settings_group_iter = gSettings.find(settings_group); LL_INFOS() << "Attempting to load settings for the group " << settings_group << " - from location " << location_key << LL_ENDL; - if(settings_group_iter == settings_r.end()) + if(settings_group_iter == gSettings.end()) { LL_WARNS() << "No matching settings group for name " << settings_group << LL_ENDL; continue; @@ -2080,7 +2082,7 @@ bool LLAppViewer::loadSettingsFromDirectory(settings_map_type const& settings_r, std::string custom_name_setting = file.get("NameFromSetting"); // *NOTE: Regardless of the group currently being lodaed, // this setting is always read from the Global settings. - LLControlGroup const* control_group = settings_r.find(sGlobalSettingsName)->second; + LLControlGroup const* control_group = gSettings.find(sGlobalSettingsName)->second; if(control_group->controlExists(custom_name_setting)) { full_settings_path = control_group->getString(custom_name_setting); @@ -2139,13 +2141,11 @@ std::string LLAppViewer::getSettingsFilename(const std::string& location_key, } bool LLAppViewer::initConfiguration() -{ - settings_map_type& settings(gSettings); - +{ //Set up internal pointers - settings[sGlobalSettingsName] = &gSavedSettings; - settings[sPerAccountSettingsName] = &gSavedPerAccountSettings; - settings[sCrashSettingsName] = &gCrashSettings; + gSettings[sGlobalSettingsName] = &gSavedSettings; + gSettings[sPerAccountSettingsName] = &gSavedPerAccountSettings; + gSettings[sCrashSettingsName] = &gCrashSettings; //Load settings files list std::string settings_file_list = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "settings_files.xml"); @@ -2170,7 +2170,7 @@ bool LLAppViewer::initConfiguration() // - load defaults bool set_defaults = true; - if(!loadSettingsFromDirectory(settings, "Default", set_defaults)) + if(!loadSettingsFromDirectory("Default", set_defaults)) { std::ostringstream msg; msg << "Unable to load default settings file. The installation may be corrupted."; @@ -2326,7 +2326,7 @@ bool LLAppViewer::initConfiguration() } // - load overrides from user_settings - loadSettingsFromDirectory(settings, "User"); + loadSettingsFromDirectory("User"); // - apply command line settings clp.notify(); @@ -2375,7 +2375,7 @@ bool LLAppViewer::initConfiguration() { const std::string& name = *itr; const std::string& value = *(++itr); - LLControlVariable* c = settings[sGlobalSettingsName]->getControl(name); + LLControlVariable* c = gSettings[sGlobalSettingsName]->getControl(name); if(c) { c->setValue(value, false); diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index b06b63d0ff..ea03c8f8bd 100644 --- a/indra/newview/llappviewer.h +++ b/indra/newview/llappviewer.h @@ -36,7 +36,6 @@ #include "llallocator.h" #include "llsys.h" // for LLOSInfo #include "lltimer.h" -#include "llviewercontrol.h" // settings_map_type #include "llappcorehttp.h" class LLCommandLineParser; @@ -143,12 +142,11 @@ class LLAppViewer : public LLApp // Load settings from the location specified by loction_key. // Key availale and rules for loading, are specified in // 'app_settings/settings_files.xml' - bool loadSettingsFromDirectory(settings_map_type const& settings_r, - std::string const& location_key, + bool loadSettingsFromDirectory(const std::string& location_key, bool set_defaults = false); - std::string getSettingsFilename(std::string const& location_key, - std::string const& file); + std::string getSettingsFilename(const std::string& location_key, + const std::string& file); // For thread debugging. // llstartup needs to control init. diff --git a/indra/newview/llappviewerlinux.cpp b/indra/newview/llappviewerlinux.cpp index 764d36e4d1..8e1ba749ec 100644 --- a/indra/newview/llappviewerlinux.cpp +++ b/indra/newview/llappviewerlinux.cpp @@ -78,9 +78,6 @@ static void exceptionTerminateHandler() int main( int argc, char **argv ) { - Debug(debug::init()); - Debug(libcw_do.on()); - #if LL_SOLARIS && defined(__sparc) asm ("ta\t6"); // NOTE: Make sure memory alignment is enforced on SPARC #endif @@ -156,7 +153,7 @@ bool LLAppViewerLinux::init() bool LLAppViewerLinux::restoreErrorTrap() { - // *NOTE:Mani there is a case for implementing this or the mac. + // *NOTE:Mani there is a case for implementing this on the mac. // Linux doesn't need it to my knowledge. return true; } diff --git a/indra/newview/llcompilequeue.cpp b/indra/newview/llcompilequeue.cpp index 31f53b6bbe..13794a792f 100644 --- a/indra/newview/llcompilequeue.cpp +++ b/indra/newview/llcompilequeue.cpp @@ -501,7 +501,6 @@ void LLFloaterCompileQueue::scriptArrived(LLVFS *vfs, const LLUUID& asset_id, asset_id.toString(uuid_str); filename = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,uuid_str) + llformat(".%s",LLAssetType::lookup(type)); - const bool is_running = true; LLViewerObject* object = gObjectList.findObject(data->mTaskId); if (object) { diff --git a/indra/newview/llfilepicker.cpp b/indra/newview/llfilepicker.cpp index acd253ffb3..624cdb6499 100644 --- a/indra/newview/llfilepicker.cpp +++ b/indra/newview/llfilepicker.cpp @@ -1498,7 +1498,7 @@ BOOL LLFilePicker::getSaveFile( ESaveFilter filter, const std::string& filename suggest_ext = ".lsl"; break; case FFSAVE_IMAGE: - caption += add_imagesave_filter_to_gtkchooser(picker); + caption += add_save_texture_filter_to_gtkchooser(picker); suggest_ext = ".png"; break; default:; @@ -1540,31 +1540,31 @@ BOOL LLFilePicker::getSaveFile( ESaveFilter filter, const std::string& filename return rtn; } -std::string setup_filter(GtkWindow* picker) +std::string setup_filter(GtkWindow* picker, const LLFilePicker::ELoadFilter& filter) { std::string filtername = ""; switch (filter) { - case FFLOAD_WAV: + case LLFilePicker::FFLOAD_WAV: filtername = add_wav_filter_to_gtkchooser(picker); break; - case FFLOAD_ANIM: + case LLFilePicker::FFLOAD_ANIM: filtername = add_anim_filter_to_gtkchooser(picker); break; - case FFLOAD_XML: + case LLFilePicker::FFLOAD_XML: filtername = add_xml_filter_to_gtkchooser(picker); break; - case FFLOAD_COLLADA: + case LLFilePicker::FFLOAD_COLLADA: filtername = add_collada_filter_to_gtkchooser(picker); break; - case FFLOAD_IMAGE: + case LLFilePicker::FFLOAD_IMAGE: filtername = add_imageload_filter_to_gtkchooser(picker); break; - case FFLOAD_SCRIPT: + case LLFilePicker::FFLOAD_SCRIPT: filtername = add_script_filter_to_gtkchooser(picker); break; - case FFLOAD_DICTIONARY: + case LLFilePicker::FFLOAD_DICTIONARY: filtername = add_dictionary_filter_to_gtkchooser(picker); break; default:; @@ -1592,7 +1592,7 @@ BOOL LLFilePicker::getOpenFile( ELoadFilter filter, bool blocking ) if (picker) { std::string caption = LLTrans::getString("load_file_verb") + " "; - caption += setup_filter(picker); + caption += setup_filter(picker, filter); gtk_window_set_title(GTK_WINDOW(picker), caption.c_str()); @@ -1629,7 +1629,7 @@ BOOL LLFilePicker::getMultipleOpenFiles( ELoadFilter filter ) TRUE); std::string caption = LLTrans::getString("load_files") + ' '; - caption += setup_filter(picker); + caption += setup_filter(picker, filter); gtk_window_set_title(GTK_WINDOW(picker), caption.c_str()); gtk_widget_show_all(GTK_WIDGET(picker)); diff --git a/indra/newview/llfloaterbvhpreview.cpp b/indra/newview/llfloaterbvhpreview.cpp index 43563ebc28..5dd45badea 100644 --- a/indra/newview/llfloaterbvhpreview.cpp +++ b/indra/newview/llfloaterbvhpreview.cpp @@ -1258,16 +1258,14 @@ void LLFloaterBvhPreview::onBtnOK(void* userdata) else // { - upload_new_resource(floaterp->mTransactionID, // tid - LLAssetType::AT_ANIMATION, - name, - desc, - 0, - LLFolderType::FT_NONE, - LLInventoryType::IT_ANIMATION, - LLFloaterPerms::getNextOwnerPerms("Uploads"), LLFloaterPerms::getGroupPerms("Uploads"), LLFloaterPerms::getEveryonePerms("Uploads"), - name, - callback, expected_upload_cost, userdata); + LLResourceUploadInfo::ptr_t assetUpdloadInfo(new LLResourceUploadInfo( + floaterp->mTransactionID, LLAssetType::AT_ANIMATION, + name, desc, 0, + LLFolderType::FT_NONE, LLInventoryType::IT_ANIMATION, + LLFloaterPerms::getNextOwnerPerms("Uploads"), LLFloaterPerms::getGroupPerms("Uploads"), LLFloaterPerms::getEveryonePerms("Uploads"), + expected_upload_cost)); + + upload_new_resource(assetUpdloadInfo); } } else diff --git a/indra/newview/llfloaternamedesc.cpp b/indra/newview/llfloaternamedesc.cpp index 465b7d3762..a954d7de72 100644 --- a/indra/newview/llfloaternamedesc.cpp +++ b/indra/newview/llfloaternamedesc.cpp @@ -175,16 +175,20 @@ void LLFloaterNameDesc::onBtnOK() LLAssetStorage::LLStoreAssetCallback callback = NULL; S32 expected_upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload(); // kinda hack - assumes that unsubclassed LLFloaterNameDesc is only used for uploading chargeable assets, which it is right now (it's only used unsubclassed for the sound upload dialog, and THAT should be a subclass). void *nruserdata = NULL; - std::string display_name = LLStringUtil::null; - - upload_new_resource(mFilenameAndPath, // file - getChild("name_form")->getValue().asString(), - getChild("description_form")->getValue().asString(), - 0, LLFolderType::FT_NONE, LLInventoryType::IT_NONE, - LLFloaterPerms::getNextOwnerPerms("Uploads"), - LLFloaterPerms::getGroupPerms("Uploads"), - LLFloaterPerms::getEveryonePerms("Uploads"), - display_name, callback, expected_upload_cost, nruserdata); + //std::string display_name = LLStringUtil::null; + + LLResourceUploadInfo::ptr_t uploadInfo(new LLNewFileResourceUploadInfo( + mFilenameAndPath, + getChild("name_form")->getValue().asString(), + getChild("description_form")->getValue().asString(), 0, + LLFolderType::FT_NONE, LLInventoryType::IT_NONE, + LLFloaterPerms::getNextOwnerPerms("Uploads"), + LLFloaterPerms::getGroupPerms("Uploads"), + LLFloaterPerms::getEveryonePerms("Uploads"), + expected_upload_cost)); + + upload_new_resource(uploadInfo, callback, nruserdata); + close(false); } diff --git a/indra/newview/llfloaterpostcard.cpp b/indra/newview/llfloaterpostcard.cpp index 7f8030d191..ece5020f0c 100644 --- a/indra/newview/llfloaterpostcard.cpp +++ b/indra/newview/llfloaterpostcard.cpp @@ -241,7 +241,8 @@ LLResourceUploadInfo::ptr_t fake_resource_upload_info(const std::string name) } void LLFloaterPostcard::uploadPostcardFailure(LLSD content, const std::string& name, int mSnapshotIndex) { - LLViewerAssetUpload::HandleUploadError(LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(content), content[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_CONTENT], fake_resource_upload_info(name)); + LLResourceUploadInfo::ptr_t uploadInfo(fake_resource_upload_info(name)); + LLViewerAssetUpload::HandleUploadError(LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(content), content[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_CONTENT], uploadInfo); LLFloaterSnapshot::savePostcardDone(false, mSnapshotIndex); } diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp index 7da78d7627..c22cb7b712 100644 --- a/indra/newview/llfloatersnapshot.cpp +++ b/indra/newview/llfloatersnapshot.cpp @@ -1058,8 +1058,8 @@ LLSnapshotLivePreview::EAspectSizeProblem LLSnapshotLivePreview::getAspectSizePr if (mSnapshotType == SNAPSHOT_LOCAL && (mWidth >= window_width || mHeight >= window_height) && mWidth != width_out && mHeight != height_out) { LL_DEBUGS("DCSnapshot") << "NOT up to date: required target size " << mWidth << "x" << mHeight << - " is larger or equal the window size (" << window_width << "x" << window_height << ")"\ - " but unequal the the raw snapshot size (" << width_out << "x" << height_out << ")"\ + " is larger or equal the window size (" << window_width << "x" << window_height << ")" \ + " but unequal the the raw snapshot size (" << width_out << "x" << height_out << ")" \ " and target is disk!" << LL_ENDL; return CANNOT_RESIZE; } @@ -1400,18 +1400,18 @@ void LLSnapshotLivePreview::saveTexture() LLAssetStorage::LLStoreAssetCallback callback = &LLSnapshotLivePreview::saveTextureDone; S32 expected_upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload(); saveTextureUserData* user_data = new saveTextureUserData(this, sSnapshotIndex, gSavedSettings.getBOOL("TemporaryUpload")); - if (upload_new_resource(tid, // tid - LLAssetType::AT_TEXTURE, - "Snapshot : " + pos_string, - "Taken by " + who_took_it + " at " + pos_string, - 0, - LLFolderType::FT_SNAPSHOT_CATEGORY, - LLInventoryType::IT_SNAPSHOT, - PERM_ALL, // Note: Snapshots to inventory is a special case of content upload - LLFloaterPerms::getGroupPerms("Uploads"), // that is more permissive than other uploads - LLFloaterPerms::getEveryonePerms("Uploads"), - "Snapshot : " + pos_string, - callback, expected_upload_cost, user_data)) + LLResourceUploadInfo::ptr_t uploadInfo(new LLResourceUploadInfo(tid, // tid + LLAssetType::AT_TEXTURE, + "Snapshot : " + pos_string, + "Taken by " + who_took_it + " at " + pos_string, + 0, + LLFolderType::FT_SNAPSHOT_CATEGORY, + LLInventoryType::IT_SNAPSHOT, + PERM_ALL, // Note: Snapshots to inventory is a special case of content upload + LLFloaterPerms::getGroupPerms("Uploads"), // that is more permissive than other uploads + LLFloaterPerms::getEveryonePerms("Uploads"), + expected_upload_cost)); + if (upload_new_resource(uploadInfo, callback, user_data)) { saveTextureDone2(true, user_data); } diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index c637914cb4..d11698ee47 100644 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -73,8 +73,10 @@ #include "llselectmgr.h" #include "lltabcontainer.h" #include "lltooldraganddrop.h" +#include "lltrans.h" #include "lluictrlfactory.h" #include "llviewermessage.h" +#include "llviewerfoldertype.h" #include "llviewerobjectlist.h" #include "llviewerregion.h" #include "llviewerwindow.h" @@ -786,6 +788,1019 @@ void open_marketplace_listings() LLFloaterOutbox::showInstance(); } +// Create a new folder in destFolderId with the same name as the item name and return the uuid of the new folder +// Note: this is used locally in various situation where we need to wrap an item into a special folder +LLUUID create_folder_for_item(LLInventoryItem* item, const LLUUID& destFolderId) +{ + llassert(item); + llassert(destFolderId.notNull()); + + LLUUID created_folder_id = gInventory.createNewCategory(destFolderId, LLFolderType::FT_NONE, item->getName()); + gInventory.notifyObservers(); + + // *TODO : Create different notifications for the various cases + LLNotificationsUtil::add("OutboxFolderCreated"); + + return created_folder_id; +} + +///---------------------------------------------------------------------------- +// Marketplace functions +// +// Handles Copy and Move to or within the Marketplace listings folder. +// Handles creation of stock folders, nesting of listings and version folders, +// permission checking and listings validation. +///---------------------------------------------------------------------------- + +S32 depth_nesting_in_marketplace(LLUUID cur_uuid) +{ + // Get the marketplace listings root, exit with -1 (i.e. not under the marketplace listings root) if none + const LLUUID marketplace_listings_uuid = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false); + if (marketplace_listings_uuid.isNull()) + { + return -1; + } + // If not a descendant of the marketplace listings root, then the nesting depth is -1 by definition + if (!gInventory.isObjectDescendentOf(cur_uuid, marketplace_listings_uuid)) + { + return -1; + } + + // Iterate through the parents till we hit the marketplace listings root + // Note that the marketplace listings root itself will return 0 + S32 depth = 0; + LLInventoryObject* cur_object = gInventory.getObject(cur_uuid); + while (cur_uuid != marketplace_listings_uuid) + { + depth++; + cur_uuid = cur_object->getParentUUID(); + cur_object = gInventory.getCategory(cur_uuid); + } + return depth; +} + +// Returns the UUID of the marketplace listing this object is in +LLUUID nested_parent_id(LLUUID cur_uuid, S32 depth) +{ + if (depth < 1) + { + // For objects outside the marketplace listings root (or root itself), we return a NULL UUID + return LLUUID::null; + } + else if (depth == 1) + { + // Just under the root, we return the passed UUID itself if it's a folder, NULL otherwise (not a listing) + LLViewerInventoryCategory* cat = gInventory.getCategory(cur_uuid); + return (cat ? cur_uuid : LLUUID::null); + } + + // depth > 1 + LLInventoryObject* cur_object = gInventory.getObject(cur_uuid); + while (depth > 1) + { + depth--; + cur_uuid = cur_object->getParentUUID(); + cur_object = gInventory.getCategory(cur_uuid); + } + return cur_uuid; +} + +S32 compute_stock_count(LLUUID cat_uuid, bool force_count /* false */) +{ + // Handle the case of the folder being a stock folder immediately + LLViewerInventoryCategory* cat = gInventory.getCategory(cat_uuid); + if (!cat) + { + // Not a category so no stock count to speak of + return COMPUTE_STOCK_INFINITE; + } + if (cat->getPreferredType() == LLFolderType::FT_MARKETPLACE_STOCK) + { + if (cat->getVersion() == LLViewerInventoryCategory::VERSION_UNKNOWN) + { + // If the folder is not completely fetched, we do not want to return any confusing value that could lead to unlisting + // "COMPUTE_STOCK_NOT_EVALUATED" denotes that a stock folder has a count that cannot be evaluated at this time (folder not up to date) + return COMPUTE_STOCK_NOT_EVALUATED; + } + // Note: stock folders are *not* supposed to have nested subfolders so we stop recursion here but we count only items (subfolders will be ignored) + // Note: we *always* give a stock count for stock folders, it's useful even if the listing is unassociated + LLInventoryModel::cat_array_t* cat_array; + LLInventoryModel::item_array_t* item_array; + gInventory.getDirectDescendentsOf(cat_uuid,cat_array,item_array); + return item_array->size(); + } + + // When force_count is true, we do not do any verification of the marketplace status and simply compute + // the stock amount based on the descendent hierarchy. This is used specifically when creating a listing. + if (!force_count) + { + // Grab marketplace data for this folder + S32 depth = depth_nesting_in_marketplace(cat_uuid); + LLUUID listing_uuid = nested_parent_id(cat_uuid, depth); + if (!LLMarketplaceData::instance().isListed(listing_uuid)) + { + // If not listed, the notion of stock is meaningless so it won't be computed for any level + return COMPUTE_STOCK_INFINITE; + } + + LLUUID version_folder_uuid = LLMarketplaceData::instance().getVersionFolder(listing_uuid); + // Handle the case of the first 2 levels : listing and version folders + if (depth == 1) + { + if (version_folder_uuid.notNull()) + { + // If there is a version folder, the stock value for the listing is the version folder stock + return compute_stock_count(version_folder_uuid, true); + } + else + { + // If there's no version folder associated, the notion of stock count has no meaning + return COMPUTE_STOCK_INFINITE; + } + } + else if (depth == 2) + { + if (version_folder_uuid.notNull() && (version_folder_uuid != cat_uuid)) + { + // If there is a version folder but we're not it, our stock count is meaningless + return COMPUTE_STOCK_INFINITE; + } + } + } + + // In all other cases, the stock count is the min of stock folders count found in the descendents + // "COMPUTE_STOCK_NOT_EVALUATED" denotes that a stock folder in the hierarchy has a count that cannot be evaluated at this time (folder not up to date) + LLInventoryModel::cat_array_t* cat_array; + LLInventoryModel::item_array_t* item_array; + gInventory.getDirectDescendentsOf(cat_uuid,cat_array,item_array); + + // "COMPUTE_STOCK_INFINITE" denotes a folder that doesn't countain any stock folders in its descendents + S32 curr_count = COMPUTE_STOCK_INFINITE; + + // Note: marketplace listings have a maximum depth nesting of 4 + LLInventoryModel::cat_array_t cat_array_copy = *cat_array; + for (LLInventoryModel::cat_array_t::iterator iter = cat_array_copy.begin(); iter != cat_array_copy.end(); iter++) + { + LLInventoryCategory* category = *iter; + S32 count = compute_stock_count(category->getUUID(), true); + if ((curr_count == COMPUTE_STOCK_INFINITE) || ((count != COMPUTE_STOCK_INFINITE) && (count < curr_count))) + { + curr_count = count; + } + } + + return curr_count; +} + +// local helper +bool can_move_to_marketplace(LLInventoryItem* inv_item, std::string& tooltip_msg, bool resolve_links) +{ + // Collapse links directly to items/folders + LLViewerInventoryItem * viewer_inv_item = (LLViewerInventoryItem *) inv_item; + LLViewerInventoryItem * linked_item = viewer_inv_item->getLinkedItem(); + LLViewerInventoryCategory * linked_category = viewer_inv_item->getLinkedCategory(); + + // Linked items and folders cannot be put for sale + if (linked_category || linked_item) + { + tooltip_msg = LLTrans::getString("TooltipOutboxLinked"); + return false; + } + + // A category is always considered as passing... + if (linked_category != NULL) + { + return true; + } + + // Take the linked item if necessary + if (linked_item != NULL) + { + inv_item = linked_item; + } + + // Check that the agent has transfer permission on the item: this is required as a resident cannot + // put on sale items she cannot transfer. Proceed with move if we have permission. + bool allow_transfer = inv_item->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID()); + if (!allow_transfer) + { + tooltip_msg = LLTrans::getString("TooltipOutboxNoTransfer"); + return false; + } + + // Check worn/not worn status: worn items cannot be put on the marketplace + bool worn = get_is_item_worn(inv_item->getUUID()); + if (worn) + { + tooltip_msg = LLTrans::getString("TooltipOutboxWorn"); + return false; + } + + // Check library status: library items cannot be put on the marketplace + if (!gInventory.isObjectDescendentOf(inv_item->getUUID(), gInventory.getRootFolderID())) + { + tooltip_msg = LLTrans::getString("TooltipOutboxNotInInventory"); + return false; + } + + // Check type: for the moment, calling cards cannot be put on the marketplace + bool calling_card = (LLAssetType::AT_CALLINGCARD == inv_item->getType()); + if (calling_card) + { + tooltip_msg = LLTrans::getString("TooltipOutboxCallingCard"); + return false; + } + + return true; +} + +// local helper +// Returns the max tree length (in folder nodes) down from the argument folder +int get_folder_levels(LLInventoryCategory* inv_cat) +{ + LLInventoryModel::cat_array_t* cats; + LLInventoryModel::item_array_t* items; + gInventory.getDirectDescendentsOf(inv_cat->getUUID(), cats, items); + + int max_child_levels = 0; + + for (S32 i=0; i < cats->size(); ++i) + { + LLInventoryCategory* category = cats->at(i); + max_child_levels = llmax(max_child_levels, get_folder_levels(category)); + } + + return 1 + max_child_levels; +} + +// local helper +// Returns the distance (in folder nodes) between the ancestor and its descendant. Returns -1 if not related. +int get_folder_path_length(const LLUUID& ancestor_id, const LLUUID& descendant_id) +{ + int depth = 0; + + if (ancestor_id == descendant_id) return depth; + + const LLInventoryCategory* category = gInventory.getCategory(descendant_id); + + while (category) + { + LLUUID parent_id = category->getParentUUID(); + + if (parent_id.isNull()) break; + + depth++; + + if (parent_id == ancestor_id) return depth; + + category = gInventory.getCategory(parent_id); + } + + LL_WARNS("SLM") << "get_folder_path_length() couldn't trace a path from the descendant to the ancestor" << LL_ENDL; + return -1; +} + +// local helper +// Returns true if all items within the argument folder are fit for sale, false otherwise +bool has_correct_permissions_for_sale(LLInventoryCategory* cat, std::string& error_msg) +{ + LLInventoryModel::cat_array_t* cat_array; + LLInventoryModel::item_array_t* item_array; + gInventory.getDirectDescendentsOf(cat->getUUID(),cat_array,item_array); + + LLInventoryModel::item_array_t item_array_copy = *item_array; + + for (LLInventoryModel::item_array_t::iterator iter = item_array_copy.begin(); iter != item_array_copy.end(); iter++) + { + LLInventoryItem* item = *iter; + if (!can_move_to_marketplace(item, error_msg, false)) + { + return false; + } + } + + LLInventoryModel::cat_array_t cat_array_copy = *cat_array; + + for (LLInventoryModel::cat_array_t::iterator iter = cat_array_copy.begin(); iter != cat_array_copy.end(); iter++) + { + LLInventoryCategory* category = *iter; + if (!has_correct_permissions_for_sale(category, error_msg)) + { + return false; + } + } + return true; +} + +// Returns true if inv_item can be dropped in dest_folder, a folder nested in marketplace listings (or merchant inventory) under the root_folder root +// If returns is false, tooltip_msg contains an error message to display to the user (localized and all). +// bundle_size is the amount of sibling items that are getting moved to the marketplace at the same time. +bool can_move_item_to_marketplace(const LLInventoryCategory* root_folder, LLInventoryCategory* dest_folder, LLInventoryItem* inv_item, std::string& tooltip_msg, S32 bundle_size, bool from_paste) +{ + // Check stock folder type matches item type in marketplace listings or merchant outbox (even if of no use there for the moment) + LLViewerInventoryCategory* view_folder = dynamic_cast(dest_folder); + bool move_in_stock = (view_folder && (view_folder->getPreferredType() == LLFolderType::FT_MARKETPLACE_STOCK)); + bool accept = (view_folder && view_folder->acceptItem(inv_item)); + if (!accept) + { + tooltip_msg = LLTrans::getString("TooltipOutboxMixedStock"); + } + + // Check that the item has the right type and permissions to be sold on the marketplace + if (accept) + { + accept = can_move_to_marketplace(inv_item, tooltip_msg, true); + } + + // Check that the total amount of items won't violate the max limit on the marketplace + if (accept) + { + // If the dest folder is a stock folder, we do not count the incoming items toward the total (stock items are seen as one) + int existing_item_count = (move_in_stock ? 0 : bundle_size); + + // If the dest folder is a stock folder, we do assume that the incoming items are also stock items (they should anyway) + int existing_stock_count = (move_in_stock ? bundle_size : 0); + + int existing_folder_count = 0; + + // Get the version folder: that's where the counts start from + const LLViewerInventoryCategory * version_folder = ((root_folder && (root_folder != dest_folder)) ? gInventory.getFirstDescendantOf(root_folder->getUUID(), dest_folder->getUUID()) : NULL); + + if (version_folder) + { + if (!from_paste && gInventory.isObjectDescendentOf(inv_item->getUUID(), version_folder->getUUID())) + { + // Clear those counts or they will be counted twice because we're already inside the version category + existing_item_count = 0; + } + + LLInventoryModel::cat_array_t existing_categories; + LLInventoryModel::item_array_t existing_items; + + gInventory.collectDescendents(version_folder->getUUID(), existing_categories, existing_items, FALSE); + + existing_item_count += count_copyable_items(existing_items) + count_stock_folders(existing_categories); + existing_stock_count += count_stock_items(existing_items); + existing_folder_count += existing_categories.size(); + + // If the incoming item is a nocopy (stock) item, we need to consider that it will create a stock folder + if (!inv_item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID(), gAgent.getGroupID()) && !move_in_stock) + { + // Note : we do not assume that all incoming items are nocopy of different kinds... + existing_folder_count += 1; + } + } + + if (existing_item_count > gSavedSettings.getU32("InventoryOutboxMaxItemCount")) + { + LLStringUtil::format_map_t args; + U32 amount = gSavedSettings.getU32("InventoryOutboxMaxItemCount"); + args["[AMOUNT]"] = llformat("%d",amount); + tooltip_msg = LLTrans::getString("TooltipOutboxTooManyObjects", args); + accept = false; + } + else if (existing_stock_count > gSavedSettings.getU32("InventoryOutboxMaxStockItemCount")) + { + LLStringUtil::format_map_t args; + U32 amount = gSavedSettings.getU32("InventoryOutboxMaxStockItemCount"); + args["[AMOUNT]"] = llformat("%d",amount); + tooltip_msg = LLTrans::getString("TooltipOutboxTooManyStockItems", args); + accept = false; + } + else if (existing_folder_count > gSavedSettings.getU32("InventoryOutboxMaxFolderCount")) + { + LLStringUtil::format_map_t args; + U32 amount = gSavedSettings.getU32("InventoryOutboxMaxFolderCount"); + args["[AMOUNT]"] = llformat("%d",amount); + tooltip_msg = LLTrans::getString("TooltipOutboxTooManyFolders", args); + accept = false; + } + } + + return accept; +} + +// Returns true if inv_cat can be dropped in dest_folder, a folder nested in marketplace listings (or merchant inventory) under the root_folder root +// If returns is false, tooltip_msg contains an error message to display to the user (localized and all). +// bundle_size is the amount of sibling items that are getting moved to the marketplace at the same time. +bool can_move_folder_to_marketplace(const LLInventoryCategory* root_folder, LLInventoryCategory* dest_folder, LLInventoryCategory* inv_cat, std::string& tooltip_msg, S32 bundle_size, bool check_items, bool from_paste) +{ + bool accept = true; + + // Compute the nested folders level we'll add into with that incoming folder + int incoming_folder_depth = get_folder_levels(inv_cat); + // Compute the nested folders level we're inserting ourselves in + // Note: add 1 when inserting under a listing folder as we need to take the root listing folder in the count + int insertion_point_folder_depth = (root_folder ? get_folder_path_length(root_folder->getUUID(), dest_folder->getUUID()) + 1 : 0); + + // Get the version folder: that's where the folders and items counts start from + const LLViewerInventoryCategory * version_folder = (insertion_point_folder_depth >= 2 ? gInventory.getFirstDescendantOf(root_folder->getUUID(), dest_folder->getUUID()) : NULL); + + // Compare the whole with the nested folders depth limit + // Note: substract 2 as we leave root and version folder out of the count threshold + if ((incoming_folder_depth + insertion_point_folder_depth - 2) > (S32)(gSavedSettings.getU32("InventoryOutboxMaxFolderDepth"))) + { + LLStringUtil::format_map_t args; + U32 amount = gSavedSettings.getU32("InventoryOutboxMaxFolderDepth"); + args["[AMOUNT]"] = llformat("%d",amount); + tooltip_msg = LLTrans::getString("TooltipOutboxFolderLevels", args); + accept = false; + } + + if (accept) + { + LLInventoryModel::cat_array_t descendent_categories; + LLInventoryModel::item_array_t descendent_items; + gInventory.collectDescendents(inv_cat->getUUID(), descendent_categories, descendent_items, FALSE); + + int dragged_folder_count = descendent_categories.size() + bundle_size; // Note: We assume that we're moving a bunch of folders in. That might be wrong... + int dragged_item_count = count_copyable_items(descendent_items) + count_stock_folders(descendent_categories); + int dragged_stock_count = count_stock_items(descendent_items); + int existing_item_count = 0; + int existing_stock_count = 0; + int existing_folder_count = 0; + + if (version_folder) + { + if (!from_paste && gInventory.isObjectDescendentOf(inv_cat->getUUID(), version_folder->getUUID())) + { + // Clear those counts or they will be counted twice because we're already inside the version category + dragged_folder_count = 0; + dragged_item_count = 0; + dragged_stock_count = 0; + } + + // Tally the total number of categories and items inside the root folder + LLInventoryModel::cat_array_t existing_categories; + LLInventoryModel::item_array_t existing_items; + gInventory.collectDescendents(version_folder->getUUID(), existing_categories, existing_items, FALSE); + + existing_folder_count += existing_categories.size(); + existing_item_count += count_copyable_items(existing_items) + count_stock_folders(existing_categories); + existing_stock_count += count_stock_items(existing_items); + } + + const int total_folder_count = existing_folder_count + dragged_folder_count; + const int total_item_count = existing_item_count + dragged_item_count; + const int total_stock_count = existing_stock_count + dragged_stock_count; + + if (total_folder_count > gSavedSettings.getU32("InventoryOutboxMaxFolderCount")) + { + LLStringUtil::format_map_t args; + U32 amount = gSavedSettings.getU32("InventoryOutboxMaxFolderCount"); + args["[AMOUNT]"] = llformat("%d",amount); + tooltip_msg = LLTrans::getString("TooltipOutboxTooManyFolders", args); + accept = false; + } + else if (total_item_count > gSavedSettings.getU32("InventoryOutboxMaxItemCount")) + { + LLStringUtil::format_map_t args; + U32 amount = gSavedSettings.getU32("InventoryOutboxMaxItemCount"); + args["[AMOUNT]"] = llformat("%d",amount); + tooltip_msg = LLTrans::getString("TooltipOutboxTooManyObjects", args); + accept = false; + } + else if (total_stock_count > gSavedSettings.getU32("InventoryOutboxMaxStockItemCount")) + { + LLStringUtil::format_map_t args; + U32 amount = gSavedSettings.getU32("InventoryOutboxMaxStockItemCount"); + args["[AMOUNT]"] = llformat("%d",amount); + tooltip_msg = LLTrans::getString("TooltipOutboxTooManyStockItems", args); + accept = false; + } + + // Now check that each item in the folder can be moved in the marketplace + if (accept && check_items) + { + for (S32 i=0; i < descendent_items.size(); ++i) + { + LLInventoryItem* item = descendent_items[i]; + if (!can_move_to_marketplace(item, tooltip_msg, false)) + { + accept = false; + break; + } + } + } + } + + return accept; +} + +bool move_item_to_marketplacelistings(LLInventoryItem* inv_item, LLUUID dest_folder, bool copy) +{ + // Get the marketplace listings depth of the destination folder, exit with error if not under marketplace + S32 depth = depth_nesting_in_marketplace(dest_folder); + if (depth < 0) + { + LLSD subs; + subs["[ERROR_CODE]"] = LLTrans::getString("Marketplace Error Prefix") + LLTrans::getString("Marketplace Error Not Merchant"); + LLNotificationsUtil::add("MerchantPasteFailed", subs); + return false; + } + + // We will collapse links into items/folders + LLViewerInventoryItem * viewer_inv_item = (LLViewerInventoryItem *) inv_item; + LLViewerInventoryCategory * linked_category = viewer_inv_item->getLinkedCategory(); + + if (linked_category != NULL) + { + // Move the linked folder directly + return move_folder_to_marketplacelistings(linked_category, dest_folder, copy); + } + else + { + // Grab the linked item if any + LLViewerInventoryItem * linked_item = viewer_inv_item->getLinkedItem(); + viewer_inv_item = (linked_item != NULL ? linked_item : viewer_inv_item); + + // If we want to copy but the item is no copy, fail silently (this is a common case that doesn't warrant notification) + if (copy && !viewer_inv_item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID(), gAgent.getGroupID())) + { + return false; + } + + // Check that the agent has transfer permission on the item: this is required as a resident cannot + // put on sale items she cannot transfer. Proceed with move if we have permission. + std::string error_msg; + if (can_move_to_marketplace(inv_item, error_msg, true)) + { + // When moving an isolated item, we might need to create the folder structure to support it + if (depth == 0) + { + // We need a listing folder + dest_folder = gInventory.createNewCategory(dest_folder, LLFolderType::FT_NONE, viewer_inv_item->getName()); + depth++; + } + if (depth == 1) + { + // We need a version folder + dest_folder = gInventory.createNewCategory(dest_folder, LLFolderType::FT_NONE, viewer_inv_item->getName()); + depth++; + } + LLViewerInventoryCategory* dest_cat = gInventory.getCategory(dest_folder); + if (!viewer_inv_item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID(), gAgent.getGroupID()) && + (dest_cat->getPreferredType() != LLFolderType::FT_MARKETPLACE_STOCK)) + { + // We need to create a stock folder to move a no copy item + dest_folder = gInventory.createNewCategory(dest_folder, LLFolderType::FT_MARKETPLACE_STOCK, viewer_inv_item->getName()); + dest_cat = gInventory.getCategory(dest_folder); + depth++; + } + + // Verify we can have this item in that destination category + if (!dest_cat->acceptItem(viewer_inv_item)) + { + LLSD subs; + subs["[ERROR_CODE]"] = LLTrans::getString("Marketplace Error Prefix") + LLTrans::getString("Marketplace Error Not Accepted"); + LLNotificationsUtil::add("MerchantPasteFailed", subs); + return false; + } + + // Get the parent folder of the moved item : we may have to update it + LLUUID src_folder = viewer_inv_item->getParentUUID(); + + if (copy) + { + // Copy the item + LLPointer cb = new LLBoostFuncInventoryCallback(boost::bind(update_folder_cb, dest_folder)); + copy_inventory_item( + gAgent.getID(), + viewer_inv_item->getPermissions().getOwner(), + viewer_inv_item->getUUID(), + dest_folder, + std::string(), + cb); + } + else + { + // Reparent the item + gInventory.changeItemParent(viewer_inv_item, dest_folder, true); + } + } + else + { + LLSD subs; + subs["[ERROR_CODE]"] = LLTrans::getString("Marketplace Error Prefix") + error_msg; + LLNotificationsUtil::add("MerchantPasteFailed", subs); + return false; + } + } + + open_marketplace_listings(); + return true; +} + +bool move_folder_to_marketplacelistings(LLInventoryCategory* inv_cat, const LLUUID& dest_folder, bool copy, bool move_no_copy_items) +{ + // Check that we have adequate permission on all items being moved. Proceed if we do. + std::string error_msg; + if (has_correct_permissions_for_sale(inv_cat, error_msg)) + { + // Get the destination folder + LLViewerInventoryCategory* dest_cat = gInventory.getCategory(dest_folder); + + // Check it's not a stock folder + if (dest_cat->getPreferredType() == LLFolderType::FT_MARKETPLACE_STOCK) + { + LLSD subs; + subs["[ERROR_CODE]"] = LLTrans::getString("Marketplace Error Prefix") + LLTrans::getString("Marketplace Error Not Accepted"); + LLNotificationsUtil::add("MerchantPasteFailed", subs); + return false; + } + + // Get the parent folder of the moved item : we may have to update it + LLUUID src_folder = inv_cat->getParentUUID(); + + LLViewerInventoryCategory * viewer_inv_cat = (LLViewerInventoryCategory *) inv_cat; + if (copy) + { + // Copy the folder + copy_inventory_category(&gInventory, viewer_inv_cat, dest_folder, LLUUID::null, move_no_copy_items); + } + else + { + // Reparent the folder + gInventory.changeCategoryParent(viewer_inv_cat, dest_folder, false); + // Check the destination folder recursively for no copy items and promote the including folders if any + validate_marketplacelistings(dest_cat); + } + + // Update the modified folders + update_marketplace_category(src_folder); + update_marketplace_category(dest_folder); + gInventory.notifyObservers(); + } + else + { + LLSD subs; + subs["[ERROR_CODE]"] = LLTrans::getString("Marketplace Error Prefix") + error_msg; + LLNotificationsUtil::add("MerchantPasteFailed", subs); + return false; + } + + open_marketplace_listings(); + return true; +} + +bool sort_alpha(const LLViewerInventoryCategory* cat1, const LLViewerInventoryCategory* cat2) +{ + return cat1->getName().compare(cat2->getName()) < 0; +} + +void dump_trace(std::string& message, S32 depth, LLError::ELevel log_level) +{ + LL_INFOS() << "validate_marketplacelistings : error = "<< log_level << ", depth = " << depth << ", message = " << message << LL_ENDL; +} + +// Make all relevant business logic checks on the marketplace listings starting with the folder as argument. +// This function does no deletion of listings but a mere audit and raises issues to the user (through the +// optional callback cb). It also returns a boolean, true if things validate, false if issues are raised. +// The only inventory changes that are done is to move and sort folders containing no-copy items to stock folders. +bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_t cb, bool fix_hierarchy, S32 depth) +{ +#if 0 + // Used only for debug + if (!cb) + { + cb = boost::bind(&dump_trace, _1, _2, _3); + } +#endif + // Folder is valid unless issue is raised + bool result = true; + + // Get the type and the depth of the folder + LLViewerInventoryCategory * viewer_cat = (LLViewerInventoryCategory *) (cat); + const LLFolderType::EType folder_type = cat->getPreferredType(); + if (depth < 0) + { + // If the depth argument was not provided, evaluate the depth directly + depth = depth_nesting_in_marketplace(cat->getUUID()); + } + if (depth < 0) + { + // If the folder is not under the marketplace listings root, we run validation as if it was a listing folder and prevent any hierarchy fix + // This allows the function to be used to pre-validate a folder anywhere in the inventory + depth = 1; + fix_hierarchy = false; + } + + // Set the indentation for print output (typically, audit button in marketplace folder floater) + std::string indent; + for (int i = 1; i < depth; i++) + { + indent += " "; + } + + // Check out that version folders are marketplace ready + if (depth == 2) + { + std::string message; + // Note: if we fix the hierarchy, we want to check the items individually, hence the last argument here + if (!can_move_folder_to_marketplace(cat, cat, cat, message, 0, fix_hierarchy)) + { + result = false; + if (cb) + { + message = indent + cat->getName() + LLTrans::getString("Marketplace Validation Error") + " " + message; + cb(message,depth,LLError::LEVEL_ERROR); + } + } + } + + // Check out that stock folders are at the right level + if ((folder_type == LLFolderType::FT_MARKETPLACE_STOCK) && (depth <= 2)) + { + if (fix_hierarchy) + { + if (cb) + { + std::string message = indent + cat->getName() + LLTrans::getString("Marketplace Validation Warning") + " " + LLTrans::getString("Marketplace Validation Warning Stock"); + cb(message,depth,LLError::LEVEL_WARN); + } + // Nest the stock folder one level deeper in a normal folder and restart from there + LLUUID parent_uuid = cat->getParentUUID(); + LLUUID folder_uuid = gInventory.createNewCategory(parent_uuid, LLFolderType::FT_NONE, cat->getName()); + LLInventoryCategory* new_cat = gInventory.getCategory(folder_uuid); + gInventory.changeCategoryParent(viewer_cat, folder_uuid, false); + result &= validate_marketplacelistings(new_cat, cb, fix_hierarchy, depth + 1); + return result; + } + else + { + result = false; + if (cb) + { + std::string message = indent + cat->getName() + LLTrans::getString("Marketplace Validation Error") + " " + LLTrans::getString("Marketplace Validation Warning Stock"); + cb(message,depth,LLError::LEVEL_ERROR); + } + } + } + + // Item sorting and validation : sorting and moving the various stock items is complicated as the set of constraints is high + // We need to: + // * separate non stock items, stock items per types in different folders + // * have stock items nested at depth 2 at least + // * never ever move the non-stock items + + LLInventoryModel::cat_array_t* cat_array; + LLInventoryModel::item_array_t* item_array; + gInventory.getDirectDescendentsOf(cat->getUUID(),cat_array,item_array); + + // We use a composite (type,permission) key on that map to store UUIDs of items of same (type,permissions) + std::map > items_vector; + + // Parse the items and create vectors of item UUIDs sorting copyable items and stock items of various types + bool has_bad_items = false; + LLInventoryModel::item_array_t item_array_copy = *item_array; + for (LLInventoryModel::item_array_t::iterator iter = item_array_copy.begin(); iter != item_array_copy.end(); iter++) + { + LLInventoryItem* item = *iter; + LLViewerInventoryItem * viewer_inv_item = (LLViewerInventoryItem *) item; + + // Test but skip items that shouldn't be there to start with, raise an error message for those + std::string error_msg; + if (!can_move_to_marketplace(item, error_msg, false)) + { + has_bad_items = true; + if (cb && fix_hierarchy) + { + std::string message = indent + viewer_inv_item->getName() + LLTrans::getString("Marketplace Validation Error") + " " + error_msg; + cb(message,depth,LLError::LEVEL_ERROR); + } + continue; + } + // Update the appropriate vector item for that type + LLInventoryType::EType type = LLInventoryType::IT_COUNT; // Default value for non stock items + U32 perms = 0; + if (!viewer_inv_item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID(), gAgent.getGroupID())) + { + // Get the item type for stock items + type = viewer_inv_item->getInventoryType(); + perms = viewer_inv_item->getPermissions().getMaskNextOwner(); + } + U32 key = (((U32)(type) & 0xFF) << 24) | (perms & 0xFFFFFF); + items_vector[key].push_back(viewer_inv_item->getUUID()); + } + + // How many types of items? Which type is it if only one? + S32 count = items_vector.size(); + U32 default_key = (U32)(LLInventoryType::IT_COUNT) << 24; // This is the key for any normal copyable item + U32 unique_key = (count == 1 ? items_vector.begin()->first : default_key); // The key in the case of one item type only + + // If we have no items in there (only folders or empty), analyze a bit further + if ((count == 0) && !has_bad_items) + { + if (cat_array->size() == 0) + { + // So we have no item and no folder. That's at least a warning. + if (depth == 2) + { + // If this is an empty version folder, warn only (listing won't be delivered by AIS, but only AIS should unlist) + if (cb) + { + std::string message = indent + cat->getName() + LLTrans::getString("Marketplace Validation Error Empty Version"); + cb(message,depth,LLError::LEVEL_WARN); + } + } + else if ((folder_type == LLFolderType::FT_MARKETPLACE_STOCK) && (depth > 2)) + { + // If this is a legit but empty stock folder, warn only (listing must stay searchable when out of stock) + if (cb) + { + std::string message = indent + cat->getName() + LLTrans::getString("Marketplace Validation Error Empty Stock"); + cb(message,depth,LLError::LEVEL_WARN); + } + } + else if (cb) + { + // We warn if there's nothing in a regular folder (may be it's an under construction listing) + std::string message = indent + cat->getName() + LLTrans::getString("Marketplace Validation Warning Empty"); + cb(message,depth,LLError::LEVEL_WARN); + } + } + else + { + // Done with that folder : Print out the folder name unless we already found an error here + if (cb && result && (depth >= 1)) + { + std::string message = indent + cat->getName() + LLTrans::getString("Marketplace Validation Log"); + cb(message,depth,LLError::LEVEL_INFO); + } + } + } + // If we have a single type of items of the right type in the right place, we're done + else if ((count == 1) && !has_bad_items && (((unique_key == default_key) && (depth > 1)) || ((folder_type == LLFolderType::FT_MARKETPLACE_STOCK) && (depth > 2) && (cat_array->size() == 0)))) + { + // Done with that folder : Print out the folder name unless we already found an error here + if (cb && result && (depth >= 1)) + { + std::string message = indent + cat->getName() + LLTrans::getString("Marketplace Validation Log"); + cb(message,depth,LLError::LEVEL_INFO); + } + } + else + { + if (fix_hierarchy && !has_bad_items) + { + // Alert the user when an existing stock folder has to be split + if ((folder_type == LLFolderType::FT_MARKETPLACE_STOCK) && ((count >= 2) || (cat_array->size() > 0))) + { + LLNotificationsUtil::add("AlertMerchantStockFolderSplit"); + } + // If we have more than 1 type of items or we are at the listing level or we have stock/no stock type mismatch, wrap the items in subfolders + if ((count > 1) || (depth == 1) || + ((folder_type == LLFolderType::FT_MARKETPLACE_STOCK) && (unique_key == default_key)) || + ((folder_type != LLFolderType::FT_MARKETPLACE_STOCK) && (unique_key != default_key))) + { + // Create one folder per vector at the right depth and of the right type + std::map >::iterator items_vector_it = items_vector.begin(); + while (items_vector_it != items_vector.end()) + { + // Create a new folder + LLUUID parent_uuid = (depth > 2 ? viewer_cat->getParentUUID() : viewer_cat->getUUID()); + LLViewerInventoryItem* viewer_inv_item = gInventory.getItem(items_vector_it->second.back()); + std::string folder_name = (depth >= 1 ? viewer_cat->getName() : viewer_inv_item->getName()); + LLFolderType::EType new_folder_type = (items_vector_it->first == default_key ? LLFolderType::FT_NONE : LLFolderType::FT_MARKETPLACE_STOCK); + if (cb) + { + std::string message = ""; + if (new_folder_type == LLFolderType::FT_MARKETPLACE_STOCK) + { + message = indent + folder_name + LLTrans::getString("Marketplace Validation Warning Create Stock"); + } + else + { + message = indent + folder_name + LLTrans::getString("Marketplace Validation Warning Create Version"); + } + cb(message,depth,LLError::LEVEL_WARN); + } + LLUUID folder_uuid = gInventory.createNewCategory(parent_uuid, new_folder_type, folder_name); + + // Move each item to the new folder + while (!items_vector_it->second.empty()) + { + LLViewerInventoryItem* viewer_inv_item = gInventory.getItem(items_vector_it->second.back()); + if (cb) + { + std::string message = indent + viewer_inv_item->getName() + LLTrans::getString("Marketplace Validation Warning Move"); + cb(message,depth,LLError::LEVEL_WARN); + } + gInventory.changeItemParent(viewer_inv_item, folder_uuid, true); + items_vector_it->second.pop_back(); + } + + // Next type + update_marketplace_category(parent_uuid); + update_marketplace_category(folder_uuid); + gInventory.notifyObservers(); + items_vector_it++; + } + } + // Stock folder should have no sub folder so reparent those up + if (folder_type == LLFolderType::FT_MARKETPLACE_STOCK) + { + LLUUID parent_uuid = cat->getParentUUID(); + gInventory.getDirectDescendentsOf(cat->getUUID(),cat_array,item_array); + LLInventoryModel::cat_array_t cat_array_copy = *cat_array; + for (LLInventoryModel::cat_array_t::iterator iter = cat_array_copy.begin(); iter != cat_array_copy.end(); iter++) + { + LLViewerInventoryCategory * viewer_cat = (LLViewerInventoryCategory *) (*iter); + gInventory.changeCategoryParent(viewer_cat, parent_uuid, false); + result &= validate_marketplacelistings(viewer_cat, cb, fix_hierarchy, depth); + } + } + } + else if (cb) + { + // We are not fixing the hierarchy but reporting problems, report everything we can find + // Print the folder name + if (result && (depth >= 1)) + { + if ((folder_type == LLFolderType::FT_MARKETPLACE_STOCK) && (count >= 2)) + { + // Report if a stock folder contains a mix of items + result = false; + std::string message = indent + cat->getName() + LLTrans::getString("Marketplace Validation Error Mixed Stock"); + cb(message,depth,LLError::LEVEL_ERROR); + } + else if ((folder_type == LLFolderType::FT_MARKETPLACE_STOCK) && (cat_array->size() != 0)) + { + // Report if a stock folder contains subfolders + result = false; + std::string message = indent + cat->getName() + LLTrans::getString("Marketplace Validation Error Subfolder In Stock"); + cb(message,depth,LLError::LEVEL_ERROR); + } + else + { + // Simply print the folder name + std::string message = indent + cat->getName() + LLTrans::getString("Marketplace Validation Log"); + cb(message,depth,LLError::LEVEL_INFO); + } + } + // Scan each item and report if there's a problem + LLInventoryModel::item_array_t item_array_copy = *item_array; + for (LLInventoryModel::item_array_t::iterator iter = item_array_copy.begin(); iter != item_array_copy.end(); iter++) + { + LLInventoryItem* item = *iter; + LLViewerInventoryItem * viewer_inv_item = (LLViewerInventoryItem *) item; + std::string error_msg; + if (!can_move_to_marketplace(item, error_msg, false)) + { + // Report items that shouldn't be there to start with + result = false; + std::string message = indent + " " + viewer_inv_item->getName() + LLTrans::getString("Marketplace Validation Error") + " " + error_msg; + cb(message,depth,LLError::LEVEL_ERROR); + } + else if ((!viewer_inv_item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID(), gAgent.getGroupID())) && (folder_type != LLFolderType::FT_MARKETPLACE_STOCK)) + { + // Report stock items that are misplaced + result = false; + std::string message = indent + " " + viewer_inv_item->getName() + LLTrans::getString("Marketplace Validation Error Stock Item"); + cb(message,depth,LLError::LEVEL_ERROR); + } + else if (depth == 1) + { + // Report items not wrapped in version folder + result = false; + std::string message = indent + " " + viewer_inv_item->getName() + LLTrans::getString("Marketplace Validation Warning Unwrapped Item"); + cb(message,depth,LLError::LEVEL_ERROR); + } + } + } + + // Clean up + if (viewer_cat->getDescendentCount() == 0) + { + // Remove the current folder if it ends up empty + if (cb) + { + std::string message = indent + viewer_cat->getName() + LLTrans::getString("Marketplace Validation Warning Delete"); + cb(message,depth,LLError::LEVEL_WARN); + } + gInventory.removeCategory(cat->getUUID()); + gInventory.notifyObservers(); + return result && !has_bad_items; + } + } + + // Recursion : Perform the same validation on each nested folder + gInventory.getDirectDescendentsOf(cat->getUUID(),cat_array,item_array); + LLInventoryModel::cat_array_t cat_array_copy = *cat_array; + // Sort the folders in alphabetical order first + std::sort(cat_array_copy.begin(), cat_array_copy.end(), sort_alpha); + + for (LLInventoryModel::cat_array_t::iterator iter = cat_array_copy.begin(); iter != cat_array_copy.end(); iter++) + { + LLInventoryCategory* category = *iter; + result &= validate_marketplacelistings(category, cb, fix_hierarchy, depth + 1); + } + + update_marketplace_category(cat->getUUID()); + gInventory.notifyObservers(); + return result && !has_bad_items; +} + LLUUID create_folder_in_outbox_for_item(LLInventoryItem* item, const LLUUID& destFolderId, S32 operation_id) { llassert(item); @@ -794,6 +1809,7 @@ LLUUID create_folder_in_outbox_for_item(LLInventoryItem* item, const LLUUID& des LLUUID created_folder_id = gInventory.createNewCategory(destFolderId, LLFolderType::FT_NONE, item->getName()); gInventory.notifyObservers(); + // *TODO : Create different notifications for the various cases LLNotificationsUtil::add("OutboxFolderCreated"); return created_folder_id; diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp index c01efbd703..648ce80f02 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.cpp +++ b/indra/newview/llinventorymodelbackgroundfetch.cpp @@ -351,6 +351,7 @@ void LLInventoryModelBackgroundFetch::backgroundFetch() LLViewerRegion* region = gAgent.getRegion(); if (mBackgroundFetchActive && region && region->capabilitiesReceived()) { + bool use_http_inventory(); if (use_http_inventory()) { // If we'll be using the capability, we'll be sending batches and the background thing isn't as important. diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 561a1856df..a49121cc73 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -423,8 +423,8 @@ const char * const LOG_MESH = "Mesh"; // Static data and functions to measure mesh load // time metrics for a new region scene. static unsigned int metrics_teleport_start_count = 0; -boost::signals2::connection metrics_teleport_started_signal; -static void teleport_started(); +//boost::signals2::connection metrics_teleport_started_signal; +//static void teleport_started(); void on_new_single_inventory_upload_complete( LLAssetType::EType asset_type, @@ -3120,7 +3120,7 @@ void LLMeshRepository::shutdown() { LL_INFOS(LOG_MESH) << "Shutting down mesh repository." << LL_ENDL; - metrics_teleport_started_signal.disconnect(); + //metrics_teleport_started_signal.disconnect(); for (U32 i = 0; i < mUploads.size(); ++i) { @@ -4654,10 +4654,10 @@ void LLMeshRepository::metricsUpdate() // Threading: main thread only // static -void teleport_started() +/*void teleport_started() { LLMeshRepository::metricsStart(); -} +}*/ void on_new_single_inventory_upload_complete( diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp index dc196a9754..b4fc1a8ffe 100644 --- a/indra/newview/llpreviewscript.cpp +++ b/indra/newview/llpreviewscript.cpp @@ -263,6 +263,55 @@ LLScriptEdCore::~LLScriptEdCore() delete mLiveFile; } +void LLLiveLSLEditor::experienceChanged() +{ + if(mScriptEd->getAssociatedExperience() != mExperiences->getSelectedValue().asUUID()) + { + mScriptEd->enableSave(getIsModifiable()); + //getChildView("Save_btn")->setEnabled(TRUE); + mScriptEd->setAssociatedExperience(mExperiences->getSelectedValue().asUUID()); + updateExperiencePanel(); + } +} + +void LLLiveLSLEditor::onViewProfile( LLUICtrl *ui, void* userdata ) +{ + /*LLLiveLSLEditor* self = (LLLiveLSLEditor*)userdata; + + LLUUID id; + if(self->mExperienceEnabled->get()) + { + id=self->mScriptEd->getAssociatedExperience(); + if(id.notNull()) + { + LLFloaterReg::showInstance("experience_profile", id, true); + } + }*/ + +} + +void LLLiveLSLEditor::onToggleExperience( LLUICtrl *ui, void* userdata ) +{ + LLLiveLSLEditor* self = (LLLiveLSLEditor*)userdata; + + LLUUID id; + if(self->mExperienceEnabled->get()) + { + if(self->mScriptEd->getAssociatedExperience().isNull()) + { + id=self->mExperienceIds.beginArray()->asUUID(); + } + } + + if(id != self->mScriptEd->getAssociatedExperience()) + { + self->mScriptEd->enableSave(self->getIsModifiable()); + } + self->mScriptEd->setAssociatedExperience(id); + + self->updateExperiencePanel(); +} + BOOL LLScriptEdCore::postBuild() { mErrorList = getChild("lsl errors"); @@ -2279,3 +2328,18 @@ BOOL LLLiveLSLEditor::monoChecked() const } return FALSE; } + +void LLLiveLSLEditor::setAssociatedExperience( LLHandle editor, const LLSD& experience ) +{ + LLLiveLSLEditor* scriptEd = editor.get(); + if(scriptEd) + { + LLUUID id; + if(experience.has(LLExperienceCache::EXPERIENCE_ID)) + { + id=experience[LLExperienceCache::EXPERIENCE_ID].asUUID(); + } + scriptEd->mScriptEd->setAssociatedExperience(id); + scriptEd->updateExperiencePanel(); + } +} diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 4672c9c3ca..f0a1a84c1e 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -1035,7 +1035,8 @@ bool idle_startup() // Note: can't store warnings files per account because some come up before login // Overwrite default user settings with user settings - LLAppViewer::instance()->loadSettingsFromDirectory(gSettings, "Account"); + LLAppViewer::instance()->loadSettingsFromDirectory("Account"); + // Need to set the LastLogoff time here if we don't have one. LastLogoff is used for "Recent Items" calculation // and startup time is close enough if we don't have a real value. diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index 8a6abba346..32885b5f84 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -86,7 +86,9 @@ void load_default_bindings(bool zqsd); BOOL gHackGodmode = FALSE; #endif -settings_map_type gSettings; +// Should you contemplate changing the name "Global", please first grep for +// that string literal. There are at least a couple other places in the C++ +// code that assume the LLControlGroup named "Global" is gSavedSettings. LLControlGroup gSavedSettings("Global"); // saved at end of session LLControlGroup gSavedPerAccountSettings("PerAccount"); // saved at end of session LLControlGroup gColors("Colors"); // saved at end of session diff --git a/indra/newview/llviewercontrol.h b/indra/newview/llviewercontrol.h index c75bfaf455..b6065ce12f 100644 --- a/indra/newview/llviewercontrol.h +++ b/indra/newview/llviewercontrol.h @@ -49,9 +49,6 @@ extern BOOL gHackGodmode; //setting variables are declared in this function void settings_setup_listeners(); -typedef std::map settings_map_type; -extern settings_map_type gSettings; - // for the graphics settings void create_graphics_group(LLControlGroup& group); diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index 6b8c80e325..75a32837a9 100644 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -788,6 +788,36 @@ bool LLViewerInventoryCategory::exportFileLocal(LLFILE* fp) const return true; } +bool LLViewerInventoryCategory::acceptItem(LLInventoryItem* inv_item) +{ + if (!inv_item) + { + return false; + } + + // Only stock folders have limitation on which item they will accept + bool accept = true; + if (getPreferredType() == LLFolderType::FT_MARKETPLACE_STOCK) + { + // If the item is copyable (i.e. non stock) do not accept the drop in a stock folder + if (inv_item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID(), gAgent.getGroupID())) + { + accept = false; + } + else + { + LLInventoryModel::cat_array_t* cat_array; + LLInventoryModel::item_array_t* item_array; + gInventory.getDirectDescendentsOf(getUUID(),cat_array,item_array); + // Destination stock folder must be empty OR types of incoming and existing items must be identical and have the same permissions + accept = (!item_array->size() || + ((item_array->at(0)->getInventoryType() == inv_item->getInventoryType()) && + (item_array->at(0)->getPermissions().getMaskNextOwner() == inv_item->getPermissions().getMaskNextOwner()))); + } + } + return accept; +} + void LLViewerInventoryCategory::determineFolderType() { /* Do NOT uncomment this code. This is for future 2.1 support of ensembles. diff --git a/indra/newview/llviewerinventory.h b/indra/newview/llviewerinventory.h index 7b9db72342..b6621683a5 100644 --- a/indra/newview/llviewerinventory.h +++ b/indra/newview/llviewerinventory.h @@ -232,6 +232,9 @@ class LLViewerInventoryCategory : public LLInventoryCategory virtual void unpackMessage(LLMessageSystem* msg, const char* block, S32 block_num = 0); virtual BOOL unpackMessage(const LLSD& category); + // returns true if the category object will accept the incoming item + bool acceptItem(LLInventoryItem* inv_item); + private: friend class LLInventoryModel; void localizeName(); // intended to be called from the LLInventoryModel @@ -251,10 +254,10 @@ class LLInventoryCallback : public LLRefCount class LLViewerJointAttachment; -//void rez_attachment_cb(const LLUUID& inv_item, LLViewerJointAttachment *attachmentp); // [SL:KB] - Patch: Appearance-DnDWear | Checked: 2010-09-28 (Catznip-3.0.0a) | Added: Catznip-2.2.0a void rez_attachment_cb(const LLUUID& inv_item, LLViewerJointAttachment *attachmentp, bool replace = false); // [/SL:KB] +//void rez_attachment_cb(const LLUUID& inv_item, LLViewerJointAttachment *attachmentp); void activate_gesture_cb(const LLUUID& inv_item); diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp index b9dbe30191..74aabb0181 100644 --- a/indra/newview/llviewermenufile.cpp +++ b/indra/newview/llviewermenufile.cpp @@ -942,9 +942,15 @@ void upload_new_resource( } else // - upload_new_resource(tid, asset_type, name, desc, compression_info, // tid - destination_folder_type, inv_type, next_owner_perms, group_perms, everyone_perms, - display_name, callback, expected_upload_cost, userdata); + { + LLResourceUploadInfo::ptr_t uploadInfo(new LLNewFileResourceUploadInfo( + src_filename, + name, desc, compression_info, + destination_folder_type, inv_type, + next_owner_perms, group_perms, everyone_perms, + expected_upload_cost)); + upload_new_resource(uploadInfo, callback, userdata); + } } else { @@ -1007,122 +1013,133 @@ void temp_upload_callback(const LLUUID& uuid, void* user_data, S32 result, LLExt delete data; } // -void upload_done_callback(const LLUUID& uuid, void* user_data, S32 result, LLExtStat ext_status) // StoreAssetData callback (fixed) + +void upload_done_callback( + const LLUUID& uuid, + void* user_data, + S32 result, + LLExtStat ext_status) // StoreAssetData callback (fixed) { LLResourceData* data = (LLResourceData*)user_data; S32 expected_upload_cost = data ? data->mExpectedUploadCost : 0; //LLAssetType::EType pref_loc = data->mPreferredLocation; BOOL is_balance_sufficient = TRUE; - if(!data) + if(data) { - LLUploadDialog::modalUploadFinished(); - return; - } - - if(result >= 0) - { - LLFolderType::EType dest_loc = (data->mPreferredLocation == LLFolderType::FT_NONE) ? LLFolderType::assetTypeToFolderType(data->mAssetInfo.mType) : data->mPreferredLocation; - - if (LLAssetType::AT_SOUND == data->mAssetInfo.mType || - LLAssetType::AT_TEXTURE == data->mAssetInfo.mType || - LLAssetType::AT_ANIMATION == data->mAssetInfo.mType) - { - // Charge the user for the upload. - LLViewerRegion* region = gAgent.getRegion(); - - if(!(can_afford_transaction(expected_upload_cost))) - { - LLStringUtil::format_map_t args; - args["[NAME]"] = data->mAssetInfo.getName(); - args["[CURRENCY]"] = gHippoGridManager->getConnectedGrid()->getCurrencySymbol(); - args["[AMOUNT]"] = llformat("%d", expected_upload_cost); - LLFloaterBuyCurrency::buyCurrency( LLTrans::getString("UploadingCosts", args), expected_upload_cost ); - is_balance_sufficient = FALSE; - } - else if(region) - { - // Charge user for upload - gStatusBar->debitBalance(expected_upload_cost); - - LLMessageSystem* msg = gMessageSystem; - msg->newMessageFast(_PREHASH_MoneyTransferRequest); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->nextBlockFast(_PREHASH_MoneyData); - msg->addUUIDFast(_PREHASH_SourceID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_DestID, LLUUID::null); - msg->addU8("Flags", 0); - // we tell the sim how much we were expecting to pay so it - // can respond to any discrepancy - msg->addS32Fast(_PREHASH_Amount, expected_upload_cost); - msg->addU8Fast(_PREHASH_AggregatePermNextOwner, (U8)LLAggregatePermissions::AP_EMPTY); - msg->addU8Fast(_PREHASH_AggregatePermInventory, (U8)LLAggregatePermissions::AP_EMPTY); - msg->addS32Fast(_PREHASH_TransactionType, TRANS_UPLOAD_CHARGE); - msg->addStringFast(_PREHASH_Description, NULL); - msg->sendReliable(region->getHost()); - } - } - - if(is_balance_sufficient) + if(result >= 0) { - // Actually add the upload to inventory - LL_INFOS() << "Adding " << uuid << " to inventory." << LL_ENDL; - const LLUUID folder_id = gInventory.findCategoryUUIDForType(dest_loc); - if(folder_id.notNull()) + LLFolderType::EType dest_loc = (data->mPreferredLocation == LLFolderType::FT_NONE) ? LLFolderType::assetTypeToFolderType(data->mAssetInfo.mType) : data->mPreferredLocation; + + if (LLAssetType::AT_SOUND == data->mAssetInfo.mType || + LLAssetType::AT_TEXTURE == data->mAssetInfo.mType || + LLAssetType::AT_ANIMATION == data->mAssetInfo.mType) { - U32 next_owner_perms = data->mNextOwnerPerm; - if(PERM_NONE == next_owner_perms) + // Charge the user for the upload. + LLViewerRegion* region = gAgent.getRegion(); + + if(!(can_afford_transaction(expected_upload_cost))) { - next_owner_perms = PERM_MOVE | PERM_TRANSFER; + LLStringUtil::format_map_t args; + args["[NAME]"] = data->mAssetInfo.getName(); + args["[CURRENCY]"] = gHippoGridManager->getConnectedGrid()->getCurrencySymbol(); + args["[AMOUNT]"] = llformat("%d", expected_upload_cost); + LLFloaterBuyCurrency::buyCurrency( LLTrans::getString("UploadingCosts", args), expected_upload_cost ); + is_balance_sufficient = FALSE; + } + else if(region) + { + // Charge user for upload + gStatusBar->debitBalance(expected_upload_cost); + + LLMessageSystem* msg = gMessageSystem; + msg->newMessageFast(_PREHASH_MoneyTransferRequest); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->nextBlockFast(_PREHASH_MoneyData); + msg->addUUIDFast(_PREHASH_SourceID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_DestID, LLUUID::null); + msg->addU8("Flags", 0); + // we tell the sim how much we were expecting to pay so it + // can respond to any discrepancy + msg->addS32Fast(_PREHASH_Amount, expected_upload_cost); + msg->addU8Fast(_PREHASH_AggregatePermNextOwner, (U8)LLAggregatePermissions::AP_EMPTY); + msg->addU8Fast(_PREHASH_AggregatePermInventory, (U8)LLAggregatePermissions::AP_EMPTY); + msg->addS32Fast(_PREHASH_TransactionType, TRANS_UPLOAD_CHARGE); + msg->addStringFast(_PREHASH_Description, NULL); + msg->sendReliable(region->getHost()); } - create_inventory_item(gAgent.getID(), gAgent.getSessionID(), - folder_id, data->mAssetInfo.mTransactionID, data->mAssetInfo.getName(), - data->mAssetInfo.getDescription(), data->mAssetInfo.mType, - data->mInventoryType, NOT_WEARABLE, next_owner_perms, - LLPointer(NULL)); } - else + + if(is_balance_sufficient) { - LL_WARNS() << "Can't find a folder to put it in" << LL_ENDL; + // Actually add the upload to inventory + LL_INFOS() << "Adding " << uuid << " to inventory." << LL_ENDL; + const LLUUID folder_id = gInventory.findCategoryUUIDForType(dest_loc); + if(folder_id.notNull()) + { + U32 next_owner_perms = data->mNextOwnerPerm; + if(PERM_NONE == next_owner_perms) + { + next_owner_perms = PERM_MOVE | PERM_TRANSFER; + } + create_inventory_item(gAgent.getID(), gAgent.getSessionID(), + folder_id, data->mAssetInfo.mTransactionID, data->mAssetInfo.getName(), + data->mAssetInfo.getDescription(), data->mAssetInfo.mType, + data->mInventoryType, NOT_WEARABLE, next_owner_perms, + LLPointer(NULL)); + } + else + { + LL_WARNS() << "Can't find a folder to put it in" << LL_ENDL; + } } } + else // if(result >= 0) + { + LLSD args; + args["FILE"] = LLInventoryType::lookupHumanReadable(data->mInventoryType); + args["REASON"] = std::string(LLAssetStorage::getErrorString(result)); + LLNotificationsUtil::add("CannotUploadReason", args); + } + + delete data; + data = NULL; } - else // if(result >= 0) - { - LLSD args; - args["FILE"] = LLInventoryType::lookupHumanReadable(data->mInventoryType); - args["REASON"] = std::string(LLAssetStorage::getErrorString(result)); - LLNotificationsUtil::add("CannotUploadReason", args); - } - - delete data; - data = NULL; LLUploadDialog::modalUploadFinished(); -} - -static LLAssetID upload_new_resource_prep( - const LLTransactionID& tid, - LLAssetType::EType asset_type, - LLInventoryType::EType& inventory_type, - std::string& name, - const std::string& display_name, - std::string& description) -{ - LLAssetID uuid = generate_asset_id_for_new_upload(tid); - - increase_new_upload_stats(asset_type); - - assign_defaults_and_show_upload_message( - asset_type, - inventory_type, - name, - display_name, - description); - return uuid; + // *NOTE: This is a pretty big hack. What this does is check the + // file picker if there are any more pending uploads. If so, + // upload that file. + const std::string& next_file = LLFilePicker::instance().getNextFile(); + if(is_balance_sufficient && !next_file.empty()) + { + std::string asset_name = gDirUtilp->getBaseFileName(next_file, true); + LLStringUtil::replaceNonstandardASCII( asset_name, '?' ); + LLStringUtil::replaceChar(asset_name, '|', '?'); + LLStringUtil::stripNonprintable(asset_name); + LLStringUtil::trim(asset_name); + + std::string display_name = LLStringUtil::null; + LLAssetStorage::LLStoreAssetCallback callback = NULL; + void *userdata = NULL; + upload_new_resource( + next_file, + asset_name, + asset_name, // file + 0, + LLFolderType::FT_NONE, + LLInventoryType::IT_NONE, + LLFloaterPerms::getNextOwnerPerms("Uploads"), + LLFloaterPerms::getGroupPerms("Uploads"), + LLFloaterPerms::getEveryonePerms("Uploads"), + display_name, + callback, + expected_upload_cost, // assuming next in a group of uploads is of roughly the same type, i.e. same upload cost + userdata); + } } bool upload_new_resource( diff --git a/indra/newview/llviewermenufile.h b/indra/newview/llviewermenufile.h index a593416a34..a9ad18c09d 100644 --- a/indra/newview/llviewermenufile.h +++ b/indra/newview/llviewermenufile.h @@ -52,35 +52,21 @@ class LLTransactionID; void init_menu_file(); -void upload_new_resource(const std::string& src_filename, - std::string name, - std::string desc, - S32 compression_info, - LLFolderType::EType destination_folder_type, - LLInventoryType::EType inv_type, - U32 next_owner_perms, - U32 group_perms, - U32 everyone_perms, - const std::string& display_name, - LLAssetStorage::LLStoreAssetCallback callback, - S32 expected_upload_cost, - void *userdata); - -// Return false if no upload attempt was done (and the callback will not be called). -bool upload_new_resource(const LLTransactionID &tid, - LLAssetType::EType type, - std::string name, - std::string desc, - S32 compression_info, - LLFolderType::EType destination_folder_type, - LLInventoryType::EType inv_type, - U32 next_owner_perms, - U32 group_perms, - U32 everyone_perms, - const std::string& display_name, - LLAssetStorage::LLStoreAssetCallback callback, - S32 expected_upload_cost, - void *userdata); + +void upload_new_resource( + const std::string& src_filename, + std::string name, + std::string desc, + S32 compression_info, + LLFolderType::EType destination_folder_type, + LLInventoryType::EType inv_type, + U32 next_owner_perms, + U32 group_perms, + U32 everyone_perms, + const std::string& display_name, + LLAssetStorage::LLStoreAssetCallback callback, + S32 expected_upload_cost, + void *userdata); bool upload_new_resource( LLResourceUploadInfo::ptr_t &uploadInfo, diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index 7981dc989d..28dab16a09 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -118,7 +118,7 @@ void selfClearPhases() using namespace LLAvatarAppearanceDefines; -LLSD summarize_by_buckets(std::vector in_records, std::vector by_fields, std::string val_field); +LLSD summarize_by_buckets(std::vector in_records, std::vector by_fields, const std::string& val_field); /********************************************************************************* ** ** @@ -2517,7 +2517,7 @@ void LLVOAvatarSelf::checkForUnsupportedServerBakeAppearance() // query baked image service to check status. std::string image_url = gAgentAvatarp->getImageURL(TEX_HEAD_BAKED, getTE(TEX_HEAD_BAKED)->getID()); - LLCoreHttpUtil::HttpCoroutineAdapter::callbackHttpGet(image_url, NULL, boost::bind(forceAppearanceUpdate)); + LLCoreHttpUtil::HttpCoroutineAdapter::callbackHttpGet(image_url, 0, boost::bind(forceAppearanceUpdate)); } const LLUUID& LLVOAvatarSelf::grabBakedTexture(EBakedTextureIndex baked_index) const diff --git a/indra/newview/sgmemstat.cpp b/indra/newview/sgmemstat.cpp index ca4ce05932..f87abf560d 100644 --- a/indra/newview/sgmemstat.cpp +++ b/indra/newview/sgmemstat.cpp @@ -17,6 +17,7 @@ #include "llviewerprecompiledheaders.h" #include "sgmemstat.h" +#include "apr_dso.h" #if (!LL_LINUX && !LL_USE_TCMALLOC) bool SGMemStat::haveStat() { @@ -50,12 +51,10 @@ static void initialize() { static bool initialized = false; if (!initialized) { apr_dso_handle_t* hprog = 0; - LLAPRPool pool; - pool.create(); #if LL_WINDOWS - apr_dso_load(&hprog, "libtcmalloc_minimal.dll", pool()); + apr_dso_load(&hprog, "libtcmalloc_minimal.dll", gAPRPoolp); #else - apr_dso_load(&hprog, 0, pool()); + apr_dso_load(&hprog, 0, gAPRPoolp); #endif apr_dso_sym((apr_dso_handle_sym_t*)&MallocExtension_GetNumericProperty, hprog, "MallocExtension_GetNumericProperty");