diff --git a/autobuild.xml b/autobuild.xml index 0c2b1db6b7..b451f64d7d 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -1008,11 +1008,11 @@ archive hash - c8024bad0445af488d355670ba13cc40 + 65d60415962cf65918c4fabe379ad43a hash_algorithm md5 url - file:///opt/firestorm/fmodstudio-2.01.08-linux64-210441517.tar.bz2 + file:///opt/firestorm/fmodstudio-2.01.09-linux64-211101316.tar.bz2 name linux64 @@ -1022,11 +1022,11 @@ archive hash - c27de9c2f8c562551773a80399d6d037 + 215de14980a03774795de8cde24f1ad5 hash_algorithm md5 url - file:///c:/cygwin/opt/firestorm/fmodstudio-2.01.08-windows-210431451.tar.bz2 + file:///c:/cygwin/opt/firestorm/fmodstudio-2.01.09-windows-211090925.tar.bz2 name windows @@ -1036,18 +1036,18 @@ archive hash - 29a66f79f7224cc17aa22d047853f7b0 + a55f9ae859a5a60285f0c6c764729194 hash_algorithm md5 url - file:///c:/cygwin/opt/firestorm/fmodstudio-2.01.08-windows64-210431454.tar.bz2 + file:///c:/cygwin/opt/firestorm/fmodstudio-2.01.09-windows64-211090927.tar.bz2 name windows64 version - 2.01.08 + 2.01.09 fontconfig @@ -1842,9 +1842,9 @@ archive hash - c1be3db6fda7054f615621e9a8139c51 + 8d0ad384de8fbbc9083cac20258fcb0c url - file:///opt/firestorm/kdu-8.0.6-darwin-202302239.tar.bz2 + file:///opt/firestorm/kdu-8.1-darwin64-210931415.tar.bz2 name darwin64 @@ -2315,18 +2315,18 @@ archive hash - c541838a933e0714a954e9ef6c89345d + 40a87f5d505a141b2ec79513a6197c35 hash_algorithm md5 url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/73387/708088/llca-202012011600.553112-common-553112.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/76516/728250/llca-202102021657.555615-common-555615.tar.bz2 name common version - 202012011600.553112 + 202102021657.555615 llphysicsextensions_source @@ -2749,26 +2749,14 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors open-libndofdev platforms - linux - - archive - - hash - 246ed298944fd5200e4cac3703d6e075 - url - http://3p.firestormviewer.org/open_libndofdev-0.9.183150124-linux-183150124.tar.bz2 - - name - linux - linux64 archive hash - db8a7126178e7230fd6917a28cd67bd7 + 88fb222412b98a7f371d6bf2ff42a973 url - http://3p.firestormviewer.org/open_libndofdev-0.9.183150121-linux64-183150121.tar.bz2 + http://3p.firestormviewer.org/open_libndofdev-0.13.211211036-linux64-211211036.tar.bz2 name linux64 @@ -3256,9 +3244,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - d463360491b6b5cb7a57cd67a90ececb + 60f008c5fd31641ad4e61ac751ce15d1 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/54838/510050/uriparser-0.8.0.1-darwin64-538968.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/75748/723495/uriparser-0.9.4-darwin64-555117.tar.bz2 name darwin64 @@ -3280,9 +3268,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - df570f2b9c0087438604a8ba4dc37a85 + 0d6832fd958ec127f089e683c9b67169 url - http://3p.firestormviewer.org/uriparser-0.8.0.1-linux64-180841550.tar.bz2 + http://3p.firestormviewer.org/uriparser-0.9.4-linux64-211210958.tar.bz2 name linux64 @@ -3292,9 +3280,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - 57a88be57694de6cf9f516125af2c4c9 + 00aff37a6f5e1fe08456702d28706cf6 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/54963/511746/uriparser-0.8.0.1-windows-538968.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/75751/723507/uriparser-0.9.4-windows-555117.tar.bz2 name windows @@ -3304,16 +3292,16 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - f39cc91f2a5dad13790ec18269844ae4 + ff27a91f3941c7bef5e1613a064cb048 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/54962/511739/uriparser-0.8.0.1-windows64-538968.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/75750/723506/uriparser-0.9.4-windows64-555117.tar.bz2 name windows64 version - 0.8.0.1 + 0.9.4 viewer-manager @@ -3334,9 +3322,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - c5ab9d9d7482e48cd76f4bf391900a8c + 6989053898b8e81e904e75553e378820 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/43369/385585/viewer_manager-2.0.531000-darwin64-531000.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/77523/735051/viewer_manager-2.0.556340-darwin64-556340.tar.bz2 name darwin64 @@ -3370,9 +3358,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - 6b10d7407686d9e12e63576256581e3e + 3446c1e54bb32542677caad0ec0d42ac url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/43370/385592/viewer_manager-2.0.531000-windows-531000.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/77525/735058/viewer_manager-2.0.556340-windows-556340.tar.bz2 name windows @@ -3383,7 +3371,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors source_type hg version - 2.0.531000 + 2.0.556340 vlc-bin diff --git a/doc/contributions.txt b/doc/contributions.txt index 6a47b53121..33958e15bc 100755 --- a/doc/contributions.txt +++ b/doc/contributions.txt @@ -228,6 +228,7 @@ Ansariel Hiller SL-13364 SL-13858 SL-13697 + SL-3136 Aralara Rajal Arare Chantilly CHUIBUG-191 @@ -265,10 +266,10 @@ Benja Kepler Benjamin Bigdipper Beq Janus BUG-227094 -Beth Walcher -Beq Janus SL-10288 SL-13583 + SL-14766 +Beth Walcher Bezilon Kasei Biancaluce Robbiani CT-225 diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake index 15af13a239..570c027fa5 100644 --- a/indra/cmake/Copy3rdPartyLibs.cmake +++ b/indra/cmake/Copy3rdPartyLibs.cmake @@ -61,6 +61,7 @@ if(WINDOWS) nghttp2.dll glod.dll libhunspell.dll + uriparser.dll ) # Only copy OpenJPEG dll if needed @@ -196,6 +197,9 @@ elseif(DARWIN) libnghttp2.dylib libnghttp2.14.dylib libnghttp2.14.19.0.dylib + liburiparser.dylib + liburiparser.1.dylib + liburiparser.1.0.27.dylib libgrowl.dylib libgrowl++.dylib ) diff --git a/indra/cmake/URIPARSER.cmake b/indra/cmake/URIPARSER.cmake index de146885a0..ecc5b74ef1 100644 --- a/indra/cmake/URIPARSER.cmake +++ b/indra/cmake/URIPARSER.cmake @@ -29,7 +29,7 @@ else (USESYSTEMLIBS) set(URIPARSER_PRELOAD_ARCHIVES -Wl,--whole-archive uriparser -Wl,--no-whole-archive) set(URIPARSER_LIBRARIES uriparser) elseif (DARWIN) - set(URIPARSER_LIBRARIES uriparser) + set(URIPARSER_LIBRARIES liburiparser.dylib) endif (WINDOWS) set(URIPARSER_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include/uriparser) endif (USESYSTEMLIBS) diff --git a/indra/llcharacter/llkeyframemotion.h b/indra/llcharacter/llkeyframemotion.h index d640556090..9a927ede9a 100644 --- a/indra/llcharacter/llkeyframemotion.h +++ b/indra/llcharacter/llkeyframemotion.h @@ -115,6 +115,15 @@ public: else return LLJoint::LOW_PRIORITY; } + virtual S32 getNumJointMotions() + { + if (mJointMotionList) + { + return mJointMotionList->getNumJointMotions(); + } + return 0; + } + virtual LLMotionBlendType getBlendType() { return NORMAL_BLEND; } // called to determine when a motion should be activated/deactivated based on avatar pixel coverage diff --git a/indra/llcharacter/llmotion.h b/indra/llcharacter/llmotion.h index 2dfc3afc7f..aaa9a146d7 100644 --- a/indra/llcharacter/llmotion.h +++ b/indra/llcharacter/llmotion.h @@ -129,6 +129,9 @@ public: // motions must report their priority level virtual LLJoint::JointPriority getPriority() = 0; + // amount of affected joints + virtual S32 getNumJointMotions() { return 0; }; + // motions must report their blend type virtual LLMotionBlendType getBlendType() = 0; diff --git a/indra/llcommon/llcoros.cpp b/indra/llcommon/llcoros.cpp index 2f1ca791ed..655763dce9 100644 --- a/indra/llcommon/llcoros.cpp +++ b/indra/llcommon/llcoros.cpp @@ -56,10 +56,6 @@ #include "stringize.h" #include "llexception.h" -#if LL_WINDOWS -#include -#endif - // static LLCoros::CoroData& LLCoros::get_CoroData(const std::string& caller) { @@ -252,29 +248,13 @@ std::string LLCoros::launch(const std::string& prefix, const callable_t& callabl #if LL_WINDOWS -static const U32 STATUS_MSC_EXCEPTION = 0xE06D7363; // compiler specific - -U32 exception_filter(U32 code, struct _EXCEPTION_POINTERS *exception_infop) -{ - if (code == STATUS_MSC_EXCEPTION) - { - // C++ exception, go on - return EXCEPTION_CONTINUE_SEARCH; - } - else - { - // handle it - return EXCEPTION_EXECUTE_HANDLER; - } -} - void LLCoros::winlevel(const callable_t& callable) { __try { callable(); } - __except (exception_filter(GetExceptionCode(), GetExceptionInformation())) + __except (msc_exception_filter(GetExceptionCode(), GetExceptionInformation())) { // convert to C++ styled exception // Note: it might be better to use _se_set_translator diff --git a/indra/llcommon/llexception.cpp b/indra/llcommon/llexception.cpp index 5ce8958687..b584b0ff8b 100644 --- a/indra/llcommon/llexception.cpp +++ b/indra/llcommon/llexception.cpp @@ -24,11 +24,14 @@ // `_GNU_SOURCE` macro or `BOOST_STACKTRACE_GNU_SOURCE_NOT_REQUIRED` if // _Unwind_Backtrace is available without `_GNU_SOURCE`." #define BOOST_STACKTRACE_GNU_SOURCE_NOT_REQUIRED + #if LL_WINDOWS // On Windows, header-only implementation causes macro collisions -- use // prebuilt library #define BOOST_STACKTRACE_LINK +#include #endif // LL_WINDOWS + #include // other Linden headers #include "llerror.h" @@ -85,3 +88,25 @@ void annotate_exception_(boost::exception& exc) // Anyway, which of us is really going to examine more than 100 frames? exc << errinfo_stacktrace(boost::stacktrace::stacktrace(1, 100)); } + +#if LL_WINDOWS + +// For windows SEH exception handling we sometimes need a filter that will +// separate C++ exceptions from C SEH exceptions +static const U32 STATUS_MSC_EXCEPTION = 0xE06D7363; // compiler specific + +U32 msc_exception_filter(U32 code, struct _EXCEPTION_POINTERS *exception_infop) +{ + if (code == STATUS_MSC_EXCEPTION) + { + // C++ exception, go on + return EXCEPTION_CONTINUE_SEARCH; + } + else + { + // handle it + return EXCEPTION_EXECUTE_HANDLER; + } +} + +#endif //LL_WINDOWS diff --git a/indra/llcommon/llexception.h b/indra/llcommon/llexception.h index 422dd8810a..375bea4a57 100644 --- a/indra/llcommon/llexception.h +++ b/indra/llcommon/llexception.h @@ -102,4 +102,14 @@ void crash_on_unhandled_exception_(const char*, int, const char*, const std::str log_unhandled_exception_(__FILE__, __LINE__, BOOST_CURRENT_FUNCTION, CONTEXT) void log_unhandled_exception_(const char*, int, const char*, const std::string&); + +#if LL_WINDOWS + +// SEH exception filtering for use in __try __except +// Separates C++ exceptions from C SEH exceptions +// Todo: might be good idea to do some kind of seh_to_msc_wrapper(function, ARGS&&); +U32 msc_exception_filter(U32 code, struct _EXCEPTION_POINTERS *exception_infop); + +#endif //LL_WINDOWS + #endif /* ! defined(LL_LLEXCEPTION_H) */ diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp index aacd32ef77..d8703b5bdf 100644 --- a/indra/llcommon/llsys.cpp +++ b/indra/llcommon/llsys.cpp @@ -55,6 +55,7 @@ #include #include #include +#include "llfasttimer.h" using namespace llsd; @@ -797,10 +798,7 @@ void LLMemoryInfo::getAvailableMemoryKB(U32Kilobytes& avail_physical_mem_kb, U32 // Sigh, this shouldn't be a static method, then we wouldn't have to // reload this data separately from refresh() - // We only care for a subset of what loadStatsMap calculates. Pass true to skip the expensive stuff - // LLSD statsMap(loadStatsMap()); - LLSD statsMap( loadStatsMap( true ) ); - // + LLSD statsMap(loadStatsMap()); avail_physical_mem_kb = (U32Kilobytes)statsMap["Avail Physical KB"].asInteger(); avail_virtual_mem_kb = (U32Kilobytes)statsMap["Avail Virtual KB"].asInteger(); @@ -936,12 +934,12 @@ LLMemoryInfo& LLMemoryInfo::refresh() return *this; } -// Add aProcessMemoryOnly, which for Windows will only call GlobalMemoryStatusEx -// This avoids calling GetPerformanceInfo which can be expensive. -//LLSD LLMemoryInfo::loadStatsMap() -LLSD LLMemoryInfo::loadStatsMap( bool aProcessMemoryOnly ) - // +static LLTrace::BlockTimerStatHandle FTM_MEMINFO_LOAD_STATS("MemInfo Load Stats"); + +LLSD LLMemoryInfo::loadStatsMap() { + LL_RECORD_BLOCK_TIME(FTM_MEMINFO_LOAD_STATS); + // This implementation is derived from stream() code (as of 2011-06-29). Stats stats; @@ -971,29 +969,11 @@ LLSD LLMemoryInfo::loadStatsMap( bool aProcessMemoryOnly ) stats.add("Avail Virtual KB", llclamp(state.ullAvailVirtual/div, U64(0), U64(S32_MAX))); // - // Early out in case only process memory is requested. - if( aProcessMemoryOnly ) - return stats.get(); - // - - PERFORMANCE_INFORMATION perf; - perf.cb = sizeof(perf); - GetPerformanceInfo(&perf, sizeof(perf)); - - SIZE_T pagekb(perf.PageSize/1024); - stats.add("CommitTotal KB", perf.CommitTotal * pagekb); - stats.add("CommitLimit KB", perf.CommitLimit * pagekb); - stats.add("CommitPeak KB", perf.CommitPeak * pagekb); - stats.add("PhysicalTotal KB", perf.PhysicalTotal * pagekb); - stats.add("PhysicalAvail KB", perf.PhysicalAvailable * pagekb); - stats.add("SystemCache KB", perf.SystemCache * pagekb); - stats.add("KernelTotal KB", perf.KernelTotal * pagekb); - stats.add("KernelPaged KB", perf.KernelPaged * pagekb); - stats.add("KernelNonpaged KB", perf.KernelNonpaged * pagekb); - stats.add("PageSize KB", pagekb); - stats.add("HandleCount", perf.HandleCount); - stats.add("ProcessCount", perf.ProcessCount); - stats.add("ThreadCount", perf.ThreadCount); + // SL-12122 - Call to GetPerformanceInfo() was removed here. Took + // on order of 10 ms, causing unacceptable frame time spike every + // second, and results were never used. If this is needed in the + // future, must find a way to avoid frame time impact (e.g. move + // to another thread, call much less often). PROCESS_MEMORY_COUNTERS_EX pmem; pmem.cb = sizeof(pmem); diff --git a/indra/llcommon/llsys.h b/indra/llcommon/llsys.h index 7c07e97aea..5ab97939b9 100644 --- a/indra/llcommon/llsys.h +++ b/indra/llcommon/llsys.h @@ -134,12 +134,7 @@ public: private: // set mStatsMap - - // Add aProcessMemoryOnly, which for Windows will only call GlobalMemoryStatusEx - // This avoids calling GetPerformanceInfo which can be expensive. - // static LLSD loadStatsMap(); - static LLSD loadStatsMap( bool aProcessMemoryOnly = false ); - // + static LLSD loadStatsMap(); // Memory stats for getStatsMap(). LLSD mStatsMap; diff --git a/indra/llcommon/lluriparser.cpp b/indra/llcommon/lluriparser.cpp index 16ff8516ae..e4f229dd16 100644 --- a/indra/llcommon/lluriparser.cpp +++ b/indra/llcommon/lluriparser.cpp @@ -29,14 +29,13 @@ #include "linden_common.h" #include "lluriparser.h" -#if !LL_WINDOWS -#include +#if LL_DARWIN +#include +#include #endif LLUriParser::LLUriParser(const std::string& u) : mTmpScheme(false), mNormalizedTmp(false), mRes(0) { - mState.uri = &mUri; - if (u.find("://") == std::string::npos) { mNormalizedUri = "http://"; @@ -55,7 +54,7 @@ LLUriParser::~LLUriParser() S32 LLUriParser::parse() { - mRes = uriParseUriA(&mState, mNormalizedUri.c_str()); + mRes = uriParseSingleUriA(&mUri, mNormalizedUri.c_str(), NULL); return mRes; } @@ -162,31 +161,69 @@ void LLUriParser::extractParts() } } +#if LL_DARWIN +typedef void(*sighandler_t)(int); +jmp_buf return_to_normalize; +void uri_signal_handler(int signal) +{ + // Apparently signal handler throwing an exception doesn't work. + // This is ugly and unsafe due to not unwinding content of uriparser library, + // but unless we have a way to catch this as NSexception, jump appears to be the only option. + longjmp(return_to_normalize, 1 /*setjmp will return this value*/); +} +#endif + S32 LLUriParser::normalize() { mNormalizedTmp = mTmpScheme; if (!mRes) { - mRes = uriNormalizeSyntaxExA(&mUri, URI_NORMALIZE_SCHEME | URI_NORMALIZE_HOST); +#if LL_DARWIN + sighandler_t last_handler; + last_handler = signal(SIGILL, &uri_signal_handler); // illegal instruction + if (setjmp(return_to_normalize)) + { + // Issue: external library crashed via signal + // If you encountered this, please try to figure out what's wrong: + // 1. Verify that library's input is 'sane' + // 2. Check if we have an NSexception to work with (unlikely) + // 3. See if passing same string causes exception to repeat + // + // Crash happens at uriNormalizeSyntaxExA + // Warning!!! This does not properly unwind stack, + // if this can be handled by NSexception, it needs to be remade + llassert(0); - if (!mRes) - { - S32 chars_required; - mRes = uriToStringCharsRequiredA(&mUri, &chars_required); + LL_WARNS() << "Uriparser crashed with SIGILL, while processing: " << mNormalizedUri << LL_ENDL; + signal(SIGILL, last_handler); + return 1; + } +#endif - if (!mRes) - { - chars_required++; - std::vector label_buf(chars_required); - mRes = uriToStringA(&label_buf[0], &mUri, chars_required, NULL); + mRes = uriNormalizeSyntaxExA(&mUri, URI_NORMALIZE_SCHEME | URI_NORMALIZE_HOST); - if (!mRes) - { - mNormalizedUri = &label_buf[mTmpScheme ? 7 : 0]; - mTmpScheme = false; - } - } - } +#if LL_DARWIN + signal(SIGILL, last_handler); +#endif + + if (!mRes) + { + S32 chars_required; + mRes = uriToStringCharsRequiredA(&mUri, &chars_required); + + if (!mRes) + { + chars_required++; + std::vector label_buf(chars_required); + mRes = uriToStringA(&label_buf[0], &mUri, chars_required, NULL); + + if (!mRes) + { + mNormalizedUri = &label_buf[mTmpScheme ? 7 : 0]; + mTmpScheme = false; + } + } + } } if(mTmpScheme) diff --git a/indra/llcommon/lluriparser.h b/indra/llcommon/lluriparser.h index 6e41cfd145..004664ac4a 100644 --- a/indra/llcommon/lluriparser.h +++ b/indra/llcommon/lluriparser.h @@ -79,7 +79,6 @@ private: std::string mFragment; std::string mNormalizedUri; - UriParserStateA mState; UriUriA mUri; S32 mRes; diff --git a/indra/llcorehttp/CMakeLists.txt b/indra/llcorehttp/CMakeLists.txt index 851996588e..e6976db46c 100644 --- a/indra/llcorehttp/CMakeLists.txt +++ b/indra/llcorehttp/CMakeLists.txt @@ -181,6 +181,7 @@ if (DARWIN) libapr-1.0.dylib libaprutil-1.0.dylib libnghttp2*.dylib + liburiparser*.dylib ${EXPAT_COPY} ) diff --git a/indra/llkdu/llimagej2ckdu.h b/indra/llkdu/llimagej2ckdu.h index 9de1159009..fae69c1e92 100644 --- a/indra/llkdu/llimagej2ckdu.h +++ b/indra/llkdu/llimagej2ckdu.h @@ -32,9 +32,9 @@ // // KDU core header files // -#ifdef LL_DARWIN -#define KDU_NO_THREADS -#endif +//#ifdef LL_DARWIN +//#define KDU_NO_THREADS +//#endif #include "kdu_elementary.h" #include "kdu_messaging.h" diff --git a/indra/llkdu/llkdumem.h b/indra/llkdu/llkdumem.h index 28164e157e..88b37105f4 100644 --- a/indra/llkdu/llkdumem.h +++ b/indra/llkdu/llkdumem.h @@ -28,9 +28,9 @@ #define LL_LLKDUMEM_H // Support classes for reading and writing from memory buffers in KDU -#ifdef LL_DARWIN -#define KDU_NO_THREADS -#endif +//#ifdef LL_DARWIN +//#define KDU_NO_THREADS +//#endif #define kdu_xxxx "kdu_image.h" #include "include_kdu_xxxx.h" diff --git a/indra/llmessage/llassetstorage.h b/indra/llmessage/llassetstorage.h index e0f22f1160..274e6a50ad 100644 --- a/indra/llmessage/llassetstorage.h +++ b/indra/llmessage/llassetstorage.h @@ -255,7 +255,7 @@ public: virtual void logAssetStorageInfo() = 0; - void checkForTimeouts(); + virtual void checkForTimeouts(); void getEstateAsset(const LLHost &object_sim, const LLUUID &agent_id, const LLUUID &session_id, const LLUUID &asset_id, LLAssetType::EType atype, EstateAssetType etype, diff --git a/indra/llmessage/llavatarnamecache.cpp b/indra/llmessage/llavatarnamecache.cpp index d9f8d49b6d..a0002e10f9 100644 --- a/indra/llmessage/llavatarnamecache.cpp +++ b/indra/llmessage/llavatarnamecache.cpp @@ -146,10 +146,10 @@ void LLAvatarNameCache::requestAvatarNameCache_(std::string url, std::vector::const_iterator it = agentIds.begin(); + for (; it != agentIds.end(); ++it) + { + const LLUUID& agent_id = *it; + LLAvatarNameCache::getInstance()->handleAgentError(agent_id); + } + return; } + + LLAvatarNameCache::getInstance()->handleAvNameCacheSuccess(results, httpResults); } - - if (!success) - { // on any sort of failure add dummy records for any agent IDs - // in this request that we do not have cached already - std::vector::const_iterator it = agentIds.begin(); - for ( ; it != agentIds.end(); ++it) - { - const LLUUID& agent_id = *it; - LLAvatarNameCache::getInstance()->handleAgentError(agent_id); - } - return; - } - - LLAvatarNameCache::getInstance()->handleAvNameCacheSuccess(results, httpResults); - } catch (...) { LOG_UNHANDLED_EXCEPTION(STRINGIZE("coroutine " << LLCoros::getName() - << "('" << url << "', " << agentIds.size() - << " http result: " << httpResults.asString() - << " Agent Ids)")); + << "('" << url << "', " + << agentIds.size() << "Agent Ids," + << " http result: " << S32(success) + << " has response: " << S32(httpResults.size()) + << ")")); throw; } } diff --git a/indra/llmessage/llcachename.cpp b/indra/llmessage/llcachename.cpp index bdfe52ebf6..851bdb41af 100644 --- a/indra/llmessage/llcachename.cpp +++ b/indra/llmessage/llcachename.cpp @@ -89,6 +89,10 @@ public: LLUUID mID; LLCacheNameSignal mSignal; LLHost mHost; + // Fix stale legacy requests + F64SecondsImplicit mRequestStart; + bool mIsGroup; + // PendingReply(const LLUUID& id, const LLHost& host) : mID(id), mHost(host) @@ -219,9 +223,13 @@ public: BOOL getName(const LLUUID& id, std::string& first, std::string& last); - boost::signals2::connection addPending(const LLUUID& id, const LLCacheNameCallback& callback); - void addPending(const LLUUID& id, const LLHost& host); - + // Fix stale legacy requests + //boost::signals2::connection addPending(const LLUUID& id, const LLCacheNameCallback& callback); + //void addPending(const LLUUID& id, const LLHost& host); + boost::signals2::connection addPending(const LLUUID& id, bool is_group, const LLCacheNameCallback& callback); + void addPending(const LLUUID& id, bool is_group, const LLHost& host); + // + void processPendingAsks(); void processPendingReplies(); void sendRequest(const char* msg_name, const AskQueue& queue); @@ -282,17 +290,31 @@ LLCacheName::Impl::~Impl() mReplyQueue.clear(); } -boost::signals2::connection LLCacheName::Impl::addPending(const LLUUID& id, const LLCacheNameCallback& callback) +// Fix stale legacy requests +//boost::signals2::connection LLCacheName::Impl::addPending(const LLUUID& id, const LLCacheNameCallback& callback) +boost::signals2::connection LLCacheName::Impl::addPending(const LLUUID& id, bool is_group, const LLCacheNameCallback& callback) +// { PendingReply* reply = new PendingReply(id, LLHost()); + // Fix stale legacy requests + reply->mIsGroup = is_group; + reply->mRequestStart = LLTimer::getElapsedSeconds(); + // boost::signals2::connection res = reply->setCallback(callback); mReplyQueue.push_back(reply); return res; } -void LLCacheName::Impl::addPending(const LLUUID& id, const LLHost& host) +// Fix stale legacy requests +//void LLCacheName::Impl::addPending(const LLUUID& id, const LLHost& host) +void LLCacheName::Impl::addPending(const LLUUID& id, bool is_group, const LLHost& host) +// { PendingReply* reply = new PendingReply(id, host); + // Fix stale legacy requests + reply->mIsGroup = is_group; + reply->mRequestStart = LLTimer::getElapsedSeconds(); + // mReplyQueue.push_back(reply); } @@ -552,7 +574,7 @@ std::string LLCacheName::buildFullName(const std::string& first, const std::stri std::string LLCacheName::cleanFullName(const std::string& full_name) { // FIRE-6659: Legacy "Resident" name toggle - return (LLAvatarName::trimResidentSurname() ? full_name : full_name.substr(0, full_name.find(" Resident"))); + return (!LLAvatarName::trimResidentSurname() ? full_name : full_name.substr(0, full_name.find(" Resident"))); // FIRE-6659: Legacy "Resident" name toggle } @@ -689,7 +711,9 @@ boost::signals2::connection LLCacheName::get(const LLUUID& id, bool is_group, co impl.mAskNameQueue.insert(id); } } - res = impl.addPending(id, callback); + // Fix stale legacy requests + //res = impl.addPending(id, callback); + res = impl.addPending(id, is_group, callback); } return res; } @@ -849,11 +873,44 @@ void LLCacheName::Impl::processPendingAsks() void LLCacheName::Impl::processPendingReplies() { // First call all the callbacks, because they might send messages. - for(ReplyQueue::iterator it = mReplyQueue.begin(); it != mReplyQueue.end(); ++it) + // Fix stale legacy requests + //for(ReplyQueue::iterator it = mReplyQueue.begin(); it != mReplyQueue.end(); ++it) + for (ReplyQueue::iterator it = mReplyQueue.begin(); it != mReplyQueue.end(); ) + // { PendingReply* reply = *it; + LLCacheNameEntry* entry = get_ptr_in_map(mCache, reply->mID); - if(!entry) continue; + // Fix stale legacy requests + //if(!entry) continue; + if (!entry) + { + static const F64SecondsImplicit TIMEOUT(10.0); + if (LLTimer::getElapsedSeconds() - reply->mRequestStart > TIMEOUT) + { + if (reply->mIsGroup) + { + (reply->mSignal)(reply->mID, "(???)", true); + } + else + { + (reply->mSignal)(reply->mID, "(???).(???)", false); + } + + // Assuming we don't need to send a reply to the simulator + // since we never received anything for this request either. + + delete reply; + it = mReplyQueue.erase(it); + continue; + } + else + { + it++; + continue; + } + } + // if (!entry->mIsGroup) { @@ -865,6 +922,9 @@ void LLCacheName::Impl::processPendingReplies() { (reply->mSignal)(reply->mID, entry->mGroupName, true); } + + // Fix stale legacy requests + it++; } // Forward on all replies, if needed. @@ -996,7 +1056,9 @@ void LLCacheName::Impl::processUUIDRequest(LLMessageSystem* msg, bool isGroup) } } - addPending(id, fromHost); + // Fix stale legacy requests + //addPending(id, fromHost); + addPending(id, isGroup, fromHost); } } } diff --git a/indra/llmessage/llcoproceduremanager.cpp b/indra/llmessage/llcoproceduremanager.cpp index 5775ab44e3..fff73ba3aa 100644 --- a/indra/llmessage/llcoproceduremanager.cpp +++ b/indra/llmessage/llcoproceduremanager.cpp @@ -47,7 +47,7 @@ static const std::map DefaultPoolSizes{ }; static const U32 DEFAULT_POOL_SIZE = 5; -static const U32 DEFAULT_QUEUE_SIZE = 4096; +const U32 LLCoprocedureManager::DEFAULT_QUEUE_SIZE = 4096; //========================================================================= class LLCoprocedurePool: private boost::noncopyable @@ -194,7 +194,7 @@ void LLCoprocedureManager::setPropertyMethods(SettingQuery_t queryfn, SettingUpd mPropertyDefineFn = updatefn; // workaround until we get mutex into initializePool - initializePool("VAssetStorage"); + initializePool("AssetStorage"); initializePool("Upload"); initializePool("AIS"); initializePool("ExpCache"); // FIRE-30731: ExpCache coroutine pool crash @@ -283,7 +283,7 @@ LLCoprocedurePool::LLCoprocedurePool(const std::string &poolName, size_t size): mPoolSize(size), mActiveCoprocsCount(0), mPending(0), - mPendingCoprocs(boost::make_shared(DEFAULT_QUEUE_SIZE)), + mPendingCoprocs(boost::make_shared(LLCoprocedureManager::DEFAULT_QUEUE_SIZE)), mHTTPPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID), mCoroMapping() { @@ -334,7 +334,7 @@ LLCoprocedurePool::LLCoprocedurePool(const std::string &poolName, size_t size): mCoroMapping.insert(CoroAdapterMap_t::value_type(pooledCoro, httpAdapter)); } - LL_INFOS("CoProcMgr") << "Created coprocedure pool named \"" << mPoolName << "\" with " << size << " items, queue max " << DEFAULT_QUEUE_SIZE << LL_ENDL; + LL_INFOS("CoProcMgr") << "Created coprocedure pool named \"" << mPoolName << "\" with " << size << " items, queue max " << LLCoprocedureManager::DEFAULT_QUEUE_SIZE << LL_ENDL; } LLCoprocedurePool::~LLCoprocedurePool() diff --git a/indra/llmessage/llcoproceduremanager.h b/indra/llmessage/llcoproceduremanager.h index 70204ba02b..d5557c129f 100644 --- a/indra/llmessage/llcoproceduremanager.h +++ b/indra/llmessage/llcoproceduremanager.h @@ -91,6 +91,9 @@ private: SettingQuery_t mPropertyQueryFn; SettingUpdate_t mPropertyDefineFn; + +public: + static const U32 DEFAULT_QUEUE_SIZE; }; #endif diff --git a/indra/llprimitive/llmaterial.cpp b/indra/llprimitive/llmaterial.cpp index a219ac1450..a1bfc4edd9 100644 --- a/indra/llprimitive/llmaterial.cpp +++ b/indra/llprimitive/llmaterial.cpp @@ -28,6 +28,8 @@ #include "llmaterial.h" +#include "../llrender/llglheaders.h" + /** * Materials cap parameters */ @@ -105,6 +107,8 @@ LLMaterial::LLMaterial() , mSpecularLightExponent(LLMaterial::DEFAULT_SPECULAR_LIGHT_EXPONENT) , mEnvironmentIntensity(LLMaterial::DEFAULT_ENV_INTENSITY) , mDiffuseAlphaMode(LLMaterial::DIFFUSE_ALPHA_MODE_BLEND) + , mDiffuseFormatPrimary(GL_RGBA) + , mDiffuseBaked(false) , mAlphaMaskCutoff(0) { } @@ -311,6 +315,20 @@ void LLMaterial::setEnvironmentIntensity(U8 intensity) mEnvironmentIntensity = intensity; } +U8 LLMaterial::getDiffuseAlphaModeRender() const +{ + if (mDiffuseBaked + || mDiffuseFormatPrimary == GL_RGBA + || mDiffuseFormatPrimary == GL_ALPHA) + { + return mDiffuseAlphaMode; + } + else + { + return DIFFUSE_ALPHA_MODE_NONE; + } +} + U8 LLMaterial::getDiffuseAlphaMode() const { return mDiffuseAlphaMode; @@ -321,6 +339,26 @@ void LLMaterial::setDiffuseAlphaMode(U8 alpha_mode) mDiffuseAlphaMode = alpha_mode; } +U32 LLMaterial::getDiffuseFormatPrimary() const +{ + return mDiffuseFormatPrimary; +} + +void LLMaterial::setDiffuseFormatPrimary(U32 format_primary) +{ + mDiffuseFormatPrimary = format_primary; +} + +bool LLMaterial::getIsDiffuseBaked() const +{ + return mDiffuseBaked; +} + +void LLMaterial::setDiffuseBaked(bool baked) +{ + mDiffuseBaked = baked; +} + U8 LLMaterial::getAlphaMaskCutoff() const { return mAlphaMaskCutoff; @@ -437,7 +475,7 @@ U32 LLMaterial::getShaderMask(U32 alpha_mode) } else { - ret = getDiffuseAlphaMode(); + ret = getDiffuseAlphaModeRender(); } llassert(ret < SHADER_COUNT); diff --git a/indra/llprimitive/llmaterial.h b/indra/llprimitive/llmaterial.h index d58b7ee812..1207917568 100644 --- a/indra/llprimitive/llmaterial.h +++ b/indra/llprimitive/llmaterial.h @@ -115,8 +115,17 @@ public: void setSpecularLightExponent(U8 exponent); U8 getEnvironmentIntensity() const; void setEnvironmentIntensity(U8 intensity); + + // getDiffuseAlphaModeRender takes into account if image supports alpha + // and returns value apropriate for render + // getDiffuseAlphaMode() returns value as is + U8 getDiffuseAlphaModeRender() const; U8 getDiffuseAlphaMode() const; void setDiffuseAlphaMode(U8 alpha_mode); + U32 getDiffuseFormatPrimary() const; + void setDiffuseFormatPrimary(U32 format_primary); + bool getIsDiffuseBaked() const; + void setDiffuseBaked(bool baked); U8 getAlphaMaskCutoff() const; void setAlphaMaskCutoff(U8 cutoff); @@ -147,6 +156,8 @@ protected: U8 mSpecularLightExponent; U8 mEnvironmentIntensity; U8 mDiffuseAlphaMode; + U32 mDiffuseFormatPrimary; // value from texture, LLGLenum, is not included in fromLLSD/asLLSD + bool mDiffuseBaked; // is not included in fromLLSD/asLLSD U8 mAlphaMaskCutoff; }; diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp index 548913ecaf..a2596335c2 100644 --- a/indra/llprimitive/llmodel.cpp +++ b/indra/llprimitive/llmodel.cpp @@ -1277,6 +1277,14 @@ bool LLModel::matchMaterialOrder(LLModel* ref, int& refFaceCnt, int& modelFaceCn LL_INFOS("MESHSKININFO")<<"Material of model is not a subset of reference."< ref->mMaterialList.size()) + { + LL_INFOS("MESHSKININFO") << "Material of model has more materials than a reference." << LL_ENDL; + // We passed isMaterialListSubset, so materials are a subset, but subset isn't supposed to be + // larger than original and if we keep going, reordering will cause a crash + return false; + } std::map index_map; diff --git a/indra/llui/llcheckboxctrl.cpp b/indra/llui/llcheckboxctrl.cpp index 1421edf9f0..f2c6935c94 100644 --- a/indra/llui/llcheckboxctrl.cpp +++ b/indra/llui/llcheckboxctrl.cpp @@ -197,10 +197,32 @@ void LLCheckBoxCtrl::clear() void LLCheckBoxCtrl::reshape(S32 width, S32 height, BOOL called_from_parent) { - S32 label_top = mLabel->getRect().mTop; - mLabel->reshapeToFitText(); + LLRect rect = getRect(); + S32 delta_width = width - rect.getWidth(); + S32 delta_height = height - rect.getHeight(); - LLRect label_rect = mLabel->getRect(); + if (delta_width || delta_height) + { + // adjust our rectangle + rect.mRight = getRect().mLeft + width; + rect.mTop = getRect().mBottom + height; + setRect(rect); + } + + // reshapeToFitText reshapes label to minimal size according to last bounding box + // it will work fine in case of decrease of space, but if we get more space or text + // becomes longer, label will fail to grow so reinit label's dimentions. + + static LLUICachedControl llcheckboxctrl_hpad("UICheckboxctrlHPad", 0); + LLRect label_rect = mLabel->getRect(); + S32 new_width = getRect().getWidth() - label_rect.mLeft - llcheckboxctrl_hpad; + label_rect.mRight = label_rect.mLeft + new_width; + mLabel->setRect(label_rect); + + S32 label_top = label_rect.mTop; + mLabel->reshapeToFitText(TRUE); + + label_rect = mLabel->getRect(); if (label_top != label_rect.mTop && mWordWrap == WRAP_DOWN) { // reshapeToFitText uses LLView::reshape() which always reshapes @@ -220,6 +242,8 @@ void LLCheckBoxCtrl::reshape(S32 width, S32 height, BOOL called_from_parent) llmax(btn_rect.getWidth(), label_rect.mRight - btn_rect.mLeft), llmax(label_rect.mTop - btn_rect.mBottom, btn_rect.getHeight())); mButton->setShape(btn_rect); + + updateBoundingRect(); } //virtual diff --git a/indra/llui/llfolderviewmodel.h b/indra/llui/llfolderviewmodel.h index a907786e99..f90981cfb3 100644 --- a/indra/llui/llfolderviewmodel.h +++ b/indra/llui/llfolderviewmodel.h @@ -205,6 +205,7 @@ public: virtual bool hasChildren() const = 0; virtual void addChild(LLFolderViewModelItem* child) = 0; virtual void removeChild(LLFolderViewModelItem* child) = 0; + virtual void clearChildren() = 0; // This method will be called to determine if a drop can be // performed, and will set drop to TRUE if a drop is @@ -311,9 +312,8 @@ public: virtual void clearChildren() { - // As this is cleaning the whole list of children wholesale, we do need to delete the pointed objects - // This is different and not equivalent to calling removeChild() on each child - std::for_each(mChildren.begin(), mChildren.end(), DeletePointer()); + // We are working with models that belong to views as LLPointers, clean the list, let poiters handle the rest + std::for_each(mChildren.begin(), mChildren.end(), [](LLFolderViewModelItem* c) {c->setParent(NULL); }); mChildren.clear(); dirtyDescendantsFilter(); dirtyFilter(); diff --git a/indra/llui/lllayoutstack.cpp b/indra/llui/lllayoutstack.cpp index 2c8a66145f..da06357417 100644 --- a/indra/llui/lllayoutstack.cpp +++ b/indra/llui/lllayoutstack.cpp @@ -166,7 +166,7 @@ void LLLayoutPanel::setVisible( BOOL visible ) void LLLayoutPanel::reshape( S32 width, S32 height, BOOL called_from_parent /*= TRUE*/ ) { - if (width == getRect().getWidth() && height == getRect().getHeight()) return; + if (width == getRect().getWidth() && height == getRect().getHeight() && !LLView::sForceReshape) return; if (!mIgnoreReshape && mAutoResize == false) { diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index 5cd3be4d69..2b57bea98e 100644 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -3303,7 +3303,7 @@ void hide_top_view( LLView* view ) // x and y are the desired location for the popup, in the spawning_view's // coordinate frame, NOT necessarily the mouse location // static -void LLMenuGL::showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y) +void LLMenuGL::showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y, S32 mouse_x, S32 mouse_y) { const S32 CURSOR_HEIGHT = 22; // Approximate "normal" cursor size const S32 CURSOR_WIDTH = 12; @@ -3334,12 +3334,6 @@ void LLMenuGL::showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y) } } - // Save click point for detecting cursor moves before mouse-up. - // Must be in local coords to compare with mouseUp events. - // If the mouse doesn't move, the menu will stay open ala the Mac. - // See also LLContextMenu::show() - S32 mouse_x, mouse_y; - // Resetting scrolling position if (menu->isScrollable() && menu->isScrollPositionOnShowReset()) { @@ -3350,7 +3344,18 @@ void LLMenuGL::showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y) menu->needsArrange(); menu->arrangeAndClear(); - LLUI::getInstance()->getMousePositionLocal(menu->getParent(), &mouse_x, &mouse_y); + if ((mouse_x == 0) || (mouse_y == 0)) + + { + // Save click point for detecting cursor moves before mouse-up. + // Must be in local coords to compare with mouseUp events. + // If the mouse doesn't move, the menu will stay open ala the Mac. + // See also LLContextMenu::show() + + LLUI::getInstance()->getMousePositionLocal(menu->getParent(), &mouse_x, &mouse_y); + } + + LLMenuHolderGL::sContextMenuSpawnPos.set(mouse_x,mouse_y); const LLRect menu_region_rect = LLMenuGL::sMenuContainer->getRect(); diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h index 8e805328b2..9f7ea44aff 100644 --- a/indra/llui/llmenugl.h +++ b/indra/llui/llmenugl.h @@ -520,7 +520,7 @@ public: void createJumpKeys(); // Show popup at a specific location, in the spawn_view's coordinate frame - static void showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y); + static void showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y, S32 mouse_x = 0, S32 mouse_y = 0); // Whether to drop shadow menu bar void setDropShadowed( const BOOL shadowed ); diff --git a/indra/llui/llscrolllistcolumn.cpp b/indra/llui/llscrolllistcolumn.cpp index cc9ff7a487..82b0415624 100644 --- a/indra/llui/llscrolllistcolumn.cpp +++ b/indra/llui/llscrolllistcolumn.cpp @@ -257,7 +257,7 @@ void LLScrollColumnHeader::updateResizeBars() for (col = 0; col < mColumn->mParentCtrl->getNumColumns(); col++) { LLScrollListColumn* columnp = mColumn->mParentCtrl->getColumn(col); - if (columnp->mHeader && columnp->mHeader->canResize()) + if (columnp && columnp->mHeader && columnp->mHeader->canResize()) { num_resizable_columns++; } @@ -269,7 +269,7 @@ void LLScrollColumnHeader::updateResizeBars() for (col = 0; col < mColumn->mParentCtrl->getNumColumns(); col++) { LLScrollListColumn* columnp = mColumn->mParentCtrl->getColumn(col); - if (!columnp->mHeader) continue; + if (!columnp || !columnp->mHeader) continue; BOOL enable = num_resizable_columns >= 2 && num_resizers_enabled < (num_resizable_columns - 1) && columnp->mHeader->canResize(); columnp->mHeader->enableResizeBar(enable); if (enable) diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index 71b5340d11..98c0919800 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -833,12 +833,12 @@ void LLScrollListCtrl::updateColumns(bool force_update) LLScrollColumnHeader* last_header = NULL; for (column_ordered_it = mColumnsIndexed.begin(); column_ordered_it != mColumnsIndexed.end(); ++column_ordered_it) { - if ((*column_ordered_it)->getWidth() < 0) + LLScrollListColumn* column = *column_ordered_it; + if (!column || column->getWidth() < 0) { // skip hidden columns continue; } - LLScrollListColumn* column = *column_ordered_it; if (column->mHeader) { diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index 3a10963424..122597ecb7 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -1257,7 +1257,7 @@ BOOL LLTextBase::handleToolTip(S32 x, S32 y, MASK mask) void LLTextBase::reshape(S32 width, S32 height, BOOL called_from_parent) { - if (width != getRect().getWidth() || height != getRect().getHeight()) + if (width != getRect().getWidth() || height != getRect().getHeight() || LLView::sForceReshape) { bool scrolled_to_bottom = mScroller ? mScroller->isAtBottom() : false; @@ -2882,7 +2882,7 @@ void LLTextBase::updateCursorXPos() mDesiredXPixel = getLocalRectFromDocIndex(mCursorPos).mLeft; } - +//virtual void LLTextBase::startOfLine() { S32 offset = getLineOffsetFromDocIndex(mCursorPos); diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h index 160861d777..9421b69c65 100644 --- a/indra/llui/lltextbase.h +++ b/indra/llui/lltextbase.h @@ -497,7 +497,7 @@ public: S32 getCursorPos() { return mCursorPos; } // [/SL:KB bool setCursorPos(S32 cursor_pos, bool keep_cursor_offset = false); - void startOfLine(); + virtual void startOfLine(); // Added virtual modifier void endOfLine(); void startOfDoc(); void endOfDoc(); diff --git a/indra/llui/lltextbox.cpp b/indra/llui/lltextbox.cpp index 82dbbb0d78..1568693c90 100644 --- a/indra/llui/lltextbox.cpp +++ b/indra/llui/lltextbox.cpp @@ -167,13 +167,13 @@ BOOL LLTextBox::setTextArg( const std::string& key, const LLStringExplicit& text } -void LLTextBox::reshapeToFitText() +void LLTextBox::reshapeToFitText(BOOL called_from_parent) { reflow(); S32 width = getTextPixelWidth(); S32 height = getTextPixelHeight(); - reshape( width + 2 * mHPad, height + 2 * mVPad, FALSE ); + reshape( width + 2 * mHPad, height + 2 * mVPad, called_from_parent ); } diff --git a/indra/llui/lltextbox.h b/indra/llui/lltextbox.h index 499042366a..1b8415b76e 100644 --- a/indra/llui/lltextbox.h +++ b/indra/llui/lltextbox.h @@ -60,7 +60,7 @@ public: void setHAlign( LLFontGL::HAlign align ) { mHAlign = align; } void setClickedCallback( boost::function cb, void* userdata = NULL ); - void reshapeToFitText(); + void reshapeToFitText(BOOL called_from_parent = FALSE); S32 getTextPixelWidth(); S32 getTextPixelHeight(); diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp index 118cc318c2..fd6b72f65f 100644 --- a/indra/llui/llurlentry.cpp +++ b/indra/llui/llurlentry.cpp @@ -586,11 +586,7 @@ LLUrlEntrySimpleSecondlifeURL::LLUrlEntrySimpleSecondlifeURL() // secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about // x-grid-location-info://lincoln.lindenlab.com/app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about // -// FIRE-11330: Names in chat get stuck as "Loading..." -//LLUrlEntryAgent::LLUrlEntryAgent() : -// mAvatarNameCacheConnection() LLUrlEntryAgent::LLUrlEntryAgent() -// { mPattern = boost::regex(APP_HEADER_REGEX "/agent/[\\da-f-]+/\\w+", boost::regex::perl|boost::regex::icase); @@ -622,7 +618,15 @@ void LLUrlEntryAgent::onAvatarNameCache(const LLUUID& id, const LLAvatarName& av_name) { // FIRE-11330: Names in chat get stuck as "Loading..." - //mAvatarNameCacheConnection.disconnect(); + //avatar_name_cache_connection_map_t::iterator it = mAvatarNameCacheConnections.find(id); + //if (it != mAvatarNameCacheConnections.end()) + //{ + // if (it->second.connected()) + // { + // it->second.disconnect(); + // } + // mAvatarNameCacheConnections.erase(it); + //} std::pair range; range = mAvatarNameCacheConnections.equal_range(id); for (avatar_name_cache_connection_map_t::iterator it = range.first; it != range.second; ++it) @@ -721,11 +725,16 @@ std::string LLUrlEntryAgent::getLabel(const std::string &url, const LLUrlLabelCa else { // FIRE-11330: Names in chat get stuck as "Loading..." - //if (mAvatarNameCacheConnection.connected()) + //avatar_name_cache_connection_map_t::iterator it = mAvatarNameCacheConnections.find(agent_id); + //if (it != mAvatarNameCacheConnections.end()) //{ - // mAvatarNameCacheConnection.disconnect(); + // if (it->second.connected()) + // { + // it->second.disconnect(); + // } + // mAvatarNameCacheConnections.erase(it); //} - //mAvatarNameCacheConnection = LLAvatarNameCache::get(agent_id, boost::bind(&LLUrlEntryAgent::onAvatarNameCache, this, _1, _2)); + //mAvatarNameCacheConnections[agent_id] = LLAvatarNameCache::get(agent_id, boost::bind(&LLUrlEntryAgent::onAvatarNameCache, this, _1, _2)); boost::signals2::connection connection = LLAvatarNameCache::get(agent_id, boost::bind(&LLUrlEntryAgent::onAvatarNameCache, this, _1, _2)); mAvatarNameCacheConnections.insert(std::make_pair(agent_id, connection)); // @@ -789,18 +798,22 @@ std::string LLUrlEntryAgent::getIcon(const std::string &url) // secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/(completename|displayname|username) // x-grid-location-info://lincoln.lindenlab.com/app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/(completename|displayname|username) // -// FIRE-11330: Names in chat get stuck as "Loading..." -//LLUrlEntryAgentName::LLUrlEntryAgentName() : -// mAvatarNameCacheConnection() LLUrlEntryAgentName::LLUrlEntryAgentName() -// {} void LLUrlEntryAgentName::onAvatarNameCache(const LLUUID& id, const LLAvatarName& av_name) { // FIRE-11330: Names in chat get stuck as "Loading..." - //mAvatarNameCacheConnection.disconnect(); + //avatar_name_cache_connection_map_t::iterator it = mAvatarNameCacheConnections.find(id); + //if (it != mAvatarNameCacheConnections.end()) + //{ + // if (it->second.connected()) + // { + // it->second.disconnect(); + // } + // mAvatarNameCacheConnections.erase(it); + //} std::pair range; range = mAvatarNameCacheConnections.equal_range(id); for (avatar_name_cache_connection_map_t::iterator it = range.first; it != range.second; ++it) @@ -847,11 +860,16 @@ std::string LLUrlEntryAgentName::getLabel(const std::string &url, const LLUrlLab else { // FIRE-11330: Names in chat get stuck as "Loading..." - //if (mAvatarNameCacheConnection.connected()) + //avatar_name_cache_connection_map_t::iterator it = mAvatarNameCacheConnections.find(agent_id); + //if (it != mAvatarNameCacheConnections.end()) //{ - // mAvatarNameCacheConnection.disconnect(); + // if (it->second.connected()) + // { + // it->second.disconnect(); + // } + // mAvatarNameCacheConnections.erase(it); //} - //mAvatarNameCacheConnection = LLAvatarNameCache::get(agent_id, boost::bind(&LLUrlEntryAgentName::onAvatarNameCache, this, _1, _2)); + //mAvatarNameCacheConnections[agent_id] = LLAvatarNameCache::get(agent_id, boost::bind(&LLUrlEntryAgentName::onAvatarNameCache, this, _1, _2)); boost::signals2::connection connection = LLAvatarNameCache::get(agent_id, boost::bind(&LLUrlEntryAgentName::onAvatarNameCache, this, _1, _2)); mAvatarNameCacheConnections.insert(std::make_pair(agent_id, connection)); // diff --git a/indra/llui/llurlentry.h b/indra/llui/llurlentry.h index 8390b8462e..6825d83f44 100644 --- a/indra/llui/llurlentry.h +++ b/indra/llui/llurlentry.h @@ -227,11 +227,6 @@ public: LLUrlEntryAgent(); ~LLUrlEntryAgent() { - // FIRE-11330: Names in chat get stuck as "Loading..." - //if (mAvatarNameCacheConnection.connected()) - //{ - // mAvatarNameCacheConnection.disconnect(); - //} for (avatar_name_cache_connection_map_t::iterator it = mAvatarNameCacheConnections.begin(); it != mAvatarNameCacheConnections.end(); ++it) { if (it->second.connected()) @@ -240,7 +235,6 @@ public: } } mAvatarNameCacheConnections.clear(); - // } /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb); /*virtual*/ std::string getIcon(const std::string &url); @@ -253,10 +247,10 @@ protected: private: void onAvatarNameCache(const LLUUID& id, const LLAvatarName& av_name); // FIRE-11330: Names in chat get stuck as "Loading..." - //boost::signals2::connection mAvatarNameCacheConnection; + //typedef std::map avatar_name_cache_connection_map_t; typedef std::multimap avatar_name_cache_connection_map_t; - avatar_name_cache_connection_map_t mAvatarNameCacheConnections; // + avatar_name_cache_connection_map_t mAvatarNameCacheConnections; }; /// @@ -270,11 +264,6 @@ public: LLUrlEntryAgentName(); ~LLUrlEntryAgentName() { - // FIRE-11330: Names in chat get stuck as "Loading..." - //if (mAvatarNameCacheConnection.connected()) - //{ - // mAvatarNameCacheConnection.disconnect(); - //} for (avatar_name_cache_connection_map_t::iterator it = mAvatarNameCacheConnections.begin(); it != mAvatarNameCacheConnections.end(); ++it) { if (it->second.connected()) @@ -283,7 +272,6 @@ public: } } mAvatarNameCacheConnections.clear(); - // } /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb); /*virtual*/ LLStyle::Params getStyle() const; @@ -293,10 +281,10 @@ protected: private: void onAvatarNameCache(const LLUUID& id, const LLAvatarName& av_name); // FIRE-11330: Names in chat get stuck as "Loading..." - //boost::signals2::connection mAvatarNameCacheConnection; + //typedef std::map avatar_name_cache_connection_map_t; typedef std::multimap avatar_name_cache_connection_map_t; - avatar_name_cache_connection_map_t mAvatarNameCacheConnections; // + avatar_name_cache_connection_map_t mAvatarNameCacheConnections; }; diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp index 84c71b9c32..654f5d63dd 100644 --- a/indra/llui/llview.cpp +++ b/indra/llui/llview.cpp @@ -1458,7 +1458,9 @@ void LLView::reshape(S32 width, S32 height, BOOL called_from_parent) S32 delta_x = child_rect.mLeft - viewp->getRect().mLeft; S32 delta_y = child_rect.mBottom - viewp->getRect().mBottom; viewp->translate( delta_x, delta_y ); - if (child_rect.getWidth() != viewp->getRect().getWidth() || child_rect.getHeight() != viewp->getRect().getHeight()) + if (child_rect.getWidth() != viewp->getRect().getWidth() + || child_rect.getHeight() != viewp->getRect().getHeight() + || sForceReshape) { viewp->reshape(child_rect.getWidth(), child_rect.getHeight()); } diff --git a/indra/llwindow/llwindow.cpp b/indra/llwindow/llwindow.cpp index f43ca28c13..34a91a6424 100644 --- a/indra/llwindow/llwindow.cpp +++ b/indra/llwindow/llwindow.cpp @@ -272,6 +272,18 @@ std::vector LLWindow::getDynamicFallbackFontList() #endif } +// static +std::vector LLWindow::getDisplaysResolutionList() +{ +#if LL_WINDOWS + return LLWindowWin32::getDisplaysResolutionList(); +#elif LL_DARWIN + return LLWindowMacOSX::getDisplaysResolutionList(); +#else + return std::vector(); +#endif +} + #define UTF16_IS_HIGH_SURROGATE(U) ((U16)((U) - 0xD800) < 0x0400) #define UTF16_IS_LOW_SURROGATE(U) ((U16)((U) - 0xDC00) < 0x0400) #define UTF16_SURROGATE_PAIR_TO_UTF32(H,L) (((H) << 10) + (L) - (0xD800 << 10) - 0xDC00 + 0x00010000) diff --git a/indra/llwindow/llwindow.h b/indra/llwindow/llwindow.h index 48194252a5..580fe37495 100644 --- a/indra/llwindow/llwindow.h +++ b/indra/llwindow/llwindow.h @@ -176,6 +176,8 @@ public: // + static std::vector getDisplaysResolutionList(); + // windows only DirectInput8 for joysticks virtual void* getDirectInput8() { return NULL; }; virtual bool getInputDevices(U32 device_type_filter, void * devices_callback, void* userdata) { return false; }; diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index e8ab882d4e..b342cef457 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -41,6 +41,7 @@ #include #include #include +#include extern BOOL gDebugWindowProc; BOOL gHiDPISupport = TRUE; @@ -1964,6 +1965,35 @@ void LLWindowMacOSX::interruptLanguageTextInput() commitCurrentPreedit(mGLView); } +std::vector LLWindowMacOSX::getDisplaysResolutionList() +{ + std::vector resolution_list; + + CGDirectDisplayID display_ids[10]; + uint32_t found_displays = 0; + CGError err = CGGetActiveDisplayList(10, display_ids, &found_displays); + + if (kCGErrorSuccess != err) + { + LL_WARNS() << "Couldn't get a list of active displays" << LL_ENDL; + return std::vector(); + } + + for (uint32_t i = 0; i < found_displays; i++) + { + S32 monitor_width = CGDisplayPixelsWide(display_ids[i]); + S32 monitor_height = CGDisplayPixelsHigh(display_ids[i]); + + std::ostringstream sstream; + sstream << monitor_width << "x" << monitor_height;; + std::string res = sstream.str(); + + resolution_list.push_back(res); + } + + return resolution_list; +} + //static std::vector LLWindowMacOSX::getDynamicFallbackFontList() { diff --git a/indra/llwindow/llwindowmacosx.h b/indra/llwindow/llwindowmacosx.h index 60450d315d..dddff3f73a 100644 --- a/indra/llwindow/llwindowmacosx.h +++ b/indra/llwindow/llwindowmacosx.h @@ -116,6 +116,8 @@ public: /*virtual*/ void openFile(const std::string& file_name); /*virtual*/ void setTitle(const std::string& title); + static std::vector getDisplaysResolutionList(); + static std::vector getDynamicFallbackFontList(); // Provide native key event data diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index 70072af3af..42f282ae45 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -38,6 +38,7 @@ // Linden library includes #include "llerror.h" +#include "llexception.h" #include "llfasttimer.h" #include "llgl.h" #include "llstring.h" @@ -121,7 +122,7 @@ void show_window_creation_error(const std::string& title) LL_WARNS("Window") << title << LL_ENDL; } -HGLRC SafeCreateContext(HDC hdc) +HGLRC SafeCreateContext(HDC &hdc) { __try { @@ -133,6 +134,22 @@ HGLRC SafeCreateContext(HDC hdc) } } +GLuint SafeChoosePixelFormat(HDC &hdc, const PIXELFORMATDESCRIPTOR *ppfd) +{ + __try + { + return ChoosePixelFormat(hdc, ppfd); + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + // convert to C++ styled exception + // C exception don't allow classes, so it's a regular char array + char integer_string[32]; + sprintf(integer_string, "SEH, code: %lu\n", GetExceptionCode()); + throw std::exception(integer_string); + } +} + //static BOOL LLWindowWin32::sIsClassRegistered = FALSE; @@ -404,6 +421,39 @@ LLWinImm::~LLWinImm() } +class LLMonitorInfo +{ +public: + + std::vector getResolutionsList() { return mResList; } + + LLMonitorInfo() + { + EnumDisplayMonitors(0, 0, MonitorEnum, (LPARAM)this); + } + +private: + + static BOOL CALLBACK MonitorEnum(HMONITOR hMon, HDC hdc, LPRECT lprcMonitor, LPARAM pData) + { + int monitor_width = lprcMonitor->right - lprcMonitor->left; + int monitor_height = lprcMonitor->bottom - lprcMonitor->top; + + std::ostringstream sstream; + sstream << monitor_width << "x" << monitor_height;; + std::string res = sstream.str(); + + LLMonitorInfo* pThis = reinterpret_cast(pData); + pThis->mResList.push_back(res); + + return TRUE; + } + + std::vector mResList; +}; + +static LLMonitorInfo sMonitorInfo; + LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks, const std::string& title, const std::string& name, S32 x, S32 y, S32 width, S32 height, U32 flags, @@ -434,8 +484,8 @@ LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks, memset(mCurrentGammaRamp, 0, sizeof(mCurrentGammaRamp)); memset(mPrevGammaRamp, 0, sizeof(mPrevGammaRamp)); mCustomGammaSet = FALSE; - mWindowHandle = NULL; // Initialize... - + mWindowHandle = NULL; + if (!SystemParametersInfo(SPI_GETMOUSEVANISH, 0, &mMouseVanish, 0)) { mMouseVanish = TRUE; @@ -1161,8 +1211,6 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BO << " Height: " << (window_rect.bottom - window_rect.top) << " Fullscreen: " << mFullscreen << LL_ENDL; - // Only try destroying an existing window - //if (!destroy_window_handler(mWindowHandle)) if (mWindowHandle && !destroy_window_handler(mWindowHandle)) { LL_WARNS("Window") << "Failed to properly close window before recreating it!" << LL_ENDL; @@ -1222,13 +1270,26 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BO LL_INFOS("Window") << "Device context retrieved." << LL_ENDL ; - if (!(pixel_format = ChoosePixelFormat(mhDC, &pfd))) - { - close(); - OSMessageBox(mCallbacks->translateString("MBPixelFmtErr"), - mCallbacks->translateString("MBError"), OSMB_OK); - return FALSE; - } + try + { + // Looks like ChoosePixelFormat can crash in case of faulty driver + if (!(pixel_format = SafeChoosePixelFormat(mhDC, &pfd))) + { + LL_WARNS("Window") << "ChoosePixelFormat failed, code: " << GetLastError() << LL_ENDL; + OSMessageBox(mCallbacks->translateString("MBPixelFmtErr"), + mCallbacks->translateString("MBError"), OSMB_OK); + close(); + return FALSE; + } + } + catch (...) + { + LOG_UNHANDLED_EXCEPTION("ChoosePixelFormat"); + OSMessageBox(mCallbacks->translateString("MBPixelFmtErr"), + mCallbacks->translateString("MBError"), OSMB_OK); + close(); + return FALSE; + } LL_INFOS("Window") << "Pixel format chosen." << LL_ENDL ; @@ -1493,7 +1554,7 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BO } // Destroy The Window - if (!destroy_window_handler(mWindowHandle)) + if (mWindowHandle && !destroy_window_handler(mWindowHandle)) { LL_WARNS("Window") << "Failed to properly close window!" << LL_ENDL; } @@ -4367,6 +4428,12 @@ F32 LLWindowWin32::getSystemUISize() return scale_value; } +//static +std::vector LLWindowWin32::getDisplaysResolutionList() +{ + return sMonitorInfo.getResolutionsList(); +} + //static std::vector LLWindowWin32::getDynamicFallbackFontList() { diff --git a/indra/llwindow/llwindowwin32.h b/indra/llwindow/llwindowwin32.h index 3d76ab76f3..e1abaea839 100644 --- a/indra/llwindow/llwindowwin32.h +++ b/indra/llwindow/llwindowwin32.h @@ -119,11 +119,15 @@ public: LLWindowCallbacks::DragNDropResult completeDragNDropRequest( const LLCoordGL gl_coord, const MASK mask, LLWindowCallbacks::DragNDropAction action, const std::string url ); + static std::vector getDisplaysResolutionList(); static std::vector getDynamicFallbackFontList(); static void setDPIAwareness(); /*virtual*/ void* getDirectInput8(); /*virtual*/ bool getInputDevices(U32 device_type_filter, void * di8_devices_callback, void* userdata); + + U32 getRawWParam() { return mRawWParam; } + protected: LLWindowWin32(LLWindowCallbacks* callbacks, const std::string& title, const std::string& name, int x, int y, int width, int height, U32 flags, diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index c77c14f31e..42a30ebe63 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -344,6 +344,7 @@ set(viewer_SOURCE_FILES llfloaterdeleteprefpreset.cpp llfloaterdestinations.cpp llfloaterdisplayname.cpp + llfloatereditenvironmentbase.cpp llfloatereditextdaycycle.cpp llfloaterenvironmentadjust.cpp llfloaterevent.cpp @@ -1114,6 +1115,7 @@ set(viewer_HEADER_FILES llfloaterdeleteprefpreset.h llfloaterdestinations.h llfloaterdisplayname.h + llfloatereditenvironmentbase.h llfloatereditextdaycycle.h llfloaterenvironmentadjust.h llfloaterevent.h @@ -2255,6 +2257,8 @@ if (WINDOWS) ${SHARED_LIB_STAGING_DIR}/Release/libhunspell.dll ${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/libhunspell.dll ${SHARED_LIB_STAGING_DIR}/Debug/libhunspell.dll + ${SHARED_LIB_STAGING_DIR}/Release/uriparser.dll + ${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/uriparser.dll ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/SLVoice.exe ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/libsndfile-1.dll ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/vivoxoal.dll diff --git a/indra/newview/NACLfloaterexploresounds.cpp b/indra/newview/NACLfloaterexploresounds.cpp index f28f675b4e..0bee4bd126 100644 --- a/indra/newview/NACLfloaterexploresounds.cpp +++ b/indra/newview/NACLfloaterexploresounds.cpp @@ -14,6 +14,7 @@ #include "llviewerregion.h" #include "fsassetblacklist.h" #include "fscommon.h" +#include "rlvhandler.h" static const size_t num_collision_sounds = 28; const LLUUID collision_sounds[num_collision_sounds] = @@ -129,9 +130,9 @@ class LLSoundHistoryItemCompare public: bool operator() (LLSoundHistoryItem first, LLSoundHistoryItem second) { - if(first.mPlaying) + if (first.mPlaying) { - if(second.mPlaying) + if (second.mPlaying) { return (first.mTimeStarted > second.mTimeStarted); } @@ -140,7 +141,7 @@ public: return true; } } - else if(second.mPlaying) + else if (second.mPlaying) { return false; } @@ -160,6 +161,7 @@ BOOL NACLFloaterExploreSounds::tick() static const std::string str_type_trigger_sound = getString("Type_llTriggerSound"); static const std::string str_type_loop_sound = getString("Type_llLoopSound"); static const std::string str_type_play_sound = getString("Type_llPlaySound"); + static const std::string str_unknown_name = LLTrans::getString("AvatarNameWaiting"); bool show_collision_sounds = mCollisionSounds->get(); bool show_repeated_assets = mRepeatedAssets->get(); @@ -175,7 +177,7 @@ BOOL NACLFloaterExploreSounds::tick() { std::map::iterator map_iter = gSoundHistory.begin(); std::map::iterator map_end = gSoundHistory.end(); - for( ; map_iter != map_end; ++map_iter) + for ( ; map_iter != map_end; ++map_iter) { history.push_back((*map_iter).second); } @@ -201,26 +203,39 @@ BOOL NACLFloaterExploreSounds::tick() std::list::iterator iter = history.begin(); std::list::iterator end = history.end(); - for( ; iter != end; ++iter) + for ( ; iter != end; ++iter) { LLSoundHistoryItem item = (*iter); bool is_avatar = item.mOwnerID == item.mSourceID; - if(is_avatar && !show_avatars) continue; + if (is_avatar && !show_avatars) + { + continue; + } bool is_object = !is_avatar; - if(is_object && !show_objects) continue; + if (is_object && !show_objects) + { + continue; + } bool is_repeated_asset = std::find(unique_asset_list.begin(), unique_asset_list.end(), item.mAssetID) != unique_asset_list.end(); - if(is_repeated_asset && !show_repeated_assets) continue; + if (is_repeated_asset && !show_repeated_assets) + { + continue; + } - if(!item.mReviewed) + if (!item.mReviewed) { item.mReviewedCollision = std::find(&collision_sounds[0], &collision_sounds[num_collision_sounds], item.mAssetID) != &collision_sounds[num_collision_sounds]; item.mReviewed = true; } + bool is_collision_sound = item.mReviewedCollision; - if(is_collision_sound && !show_collision_sounds) continue; + if (is_collision_sound && !show_collision_sounds) + { + continue; + } unique_asset_list.push_back(item.mAssetID); @@ -229,7 +244,7 @@ BOOL NACLFloaterExploreSounds::tick() LLSD& playing_column = element["columns"][0]; playing_column["column"] = "playing"; - if(item.mPlaying) + if (item.mPlaying) { playing_column["value"] = " " + str_playing; } @@ -242,7 +257,7 @@ BOOL NACLFloaterExploreSounds::tick() LLSD& type_column = element["columns"][1]; type_column["column"] = "type"; - if(item.mType == LLAudioEngine::AUDIO_TYPE_UI) + if (item.mType == LLAudioEngine::AUDIO_TYPE_UI) { // this shouldn't happen for now, as UI is forbidden in the log type_column["value"] = str_type_ui; @@ -251,19 +266,19 @@ BOOL NACLFloaterExploreSounds::tick() { std::string type; - if(is_avatar) + if (is_avatar) { type = str_type_avatar; } else { - if(item.mIsTrigger) + if (item.mIsTrigger) { type = str_type_trigger_sound; } else { - if(item.mIsLooped) + if (item.mIsLooped) { type = str_type_loop_sound; } @@ -282,11 +297,11 @@ BOOL NACLFloaterExploreSounds::tick() LLAvatarName av_name; if (LLAvatarNameCache::get(item.mOwnerID, &av_name)) { - owner_column["value"] = av_name.getCompleteName(); + owner_column["value"] = !gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES) ? av_name.getCompleteName() : RlvStrings::getAnonym(av_name); } else { - owner_column["value"] = item.mOwnerID.asString(); + owner_column["value"] = str_unknown_name; } LLSD& sound_column = element["columns"][3]; @@ -334,12 +349,16 @@ void NACLFloaterExploreSounds::handlePlayLocally() std::vector::iterator selection_iter = selection.begin(); std::vector::iterator selection_end = selection.end(); uuid_vec_t asset_list; - for( ; selection_iter != selection_end; ++selection_iter) + for ( ; selection_iter != selection_end; ++selection_iter) { LLSoundHistoryItem item = getItem((*selection_iter)->getValue()); - if(item.mID.isNull()) continue; + if (item.mID.isNull()) + { + continue; + } + // Unique assets only - if(std::find(asset_list.begin(), asset_list.end(), item.mAssetID) == asset_list.end()) + if (std::find(asset_list.begin(), asset_list.end(), item.mAssetID) == asset_list.end()) { asset_list.push_back(item.mAssetID); LLUUID audio_source_id = LLUUID::generateNewID(); @@ -355,15 +374,18 @@ void NACLFloaterExploreSounds::handleLookAt() { LLUUID selection = mHistoryScroller->getSelectedValue().asUUID(); LLSoundHistoryItem item = getItem(selection); // Single item only - if(item.mID.isNull()) return; + if (item.mID.isNull()) + { + return; + } LLVector3d pos_global = item.mPosition; // Try to find object position - if(item.mSourceID.notNull()) + if (item.mSourceID.notNull()) { LLViewerObject* object = gObjectList.findObject(item.mSourceID); - if(object) + if (object) { pos_global = object->getPositionGlobal(); } @@ -491,4 +513,3 @@ void NACLFloaterExploreSounds::onBlacklistAvatarNameCacheCallback(const LLUUID& } FSAssetBlacklist::getInstance()->addNewItemToBlacklist(asset_id, av_name.getCompleteName(), region_name, LLAssetType::AT_SOUND); } - diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt index a0b6fce83f..427dc381ad 100644 --- a/indra/newview/VIEWER_VERSION.txt +++ b/indra/newview/VIEWER_VERSION.txt @@ -1 +1 @@ -6.4.18 +6.4.19 diff --git a/indra/newview/animationexplorer.cpp b/indra/newview/animationexplorer.cpp index 5abf5ec67d..fdde7ded88 100644 --- a/indra/newview/animationexplorer.cpp +++ b/indra/newview/animationexplorer.cpp @@ -51,8 +51,9 @@ #include "llviewerwindow.h" // for gViewerWindow #include "llvoavatar.h" #include "llvoavatarself.h" // for gAgentAvatarp +#include "llavatarnamecache.h" -const S32 MAX_ANIMATIONS=100; +constexpr S32 MAX_ANIMATIONS = 100; // -------------------------------------------------------------------------- @@ -77,7 +78,7 @@ void RecentAnimationList::addAnimation(const LLUUID& id, const LLUUID& playedBy) // only remember animation when it wasn't played by ourselves or the explorer window is open, // so the list doesn't get polluted - if (playedBy != gAgentAvatarp->getID() || explorer != NULL) + if (playedBy != gAgentAvatarp->getID() || explorer) { mAnimationList.push_back(entry); @@ -114,7 +115,7 @@ void RecentAnimationList::requestList(AnimationExplorer* explorer) AnimationExplorer::AnimationExplorer(const LLSD& key) : LLFloater(key), - mPreviewCtrl(NULL), + mPreviewCtrl(nullptr), mLastMouseX(0), mLastMouseY(0) { @@ -122,7 +123,16 @@ AnimationExplorer::AnimationExplorer(const LLSD& key) AnimationExplorer::~AnimationExplorer() { - mAnimationPreview = NULL; + mAnimationPreview = nullptr; + + for (const auto& cb : mAvatarNameCacheConnections) + { + if (cb.second.connected()) + { + cb.second.disconnect(); + } + } + mAvatarNameCacheConnections.clear(); } void AnimationExplorer::startMotion(const LLUUID& motionID) @@ -363,8 +373,21 @@ void AnimationExplorer::addAnimation(const LLUUID& id, const LLUUID& played_by, // if it was an avatar, get the name here if (vo->isAvatar()) { - playedByName = std::string(vo->getNVPair("FirstName")->getString()) + " " + - std::string(vo->getNVPair("LastName")->getString()); + LLAvatarName av_name; + if (LLAvatarNameCache::get(played_by, &av_name)) + { + playedByName = av_name.getCompleteName(); + } + else + { + if (mAvatarNameCacheConnections.find(played_by) != mAvatarNameCacheConnections.end()) + { + boost::signals2::connection cb_connection = LLAvatarNameCache::get(played_by, boost::bind(&AnimationExplorer::onAvatarNameCallback, this, _1, _2)); + mAvatarNameCacheConnections.insert(std::make_pair(played_by, cb_connection)); + } + + playedByName = LLTrans::getString("AvatarNameWaiting"); + } } // not an avatar, do a lookup by UUID else @@ -425,6 +448,21 @@ void AnimationExplorer::addAnimation(const LLUUID& id, const LLUUID& played_by, mAnimationScrollList->addElement(item, ADD_TOP); } +void AnimationExplorer::onAvatarNameCallback(const LLUUID& id, const LLAvatarName& av_name) +{ + auto iter = mAvatarNameCacheConnections.find(id); + if (iter != mAvatarNameCacheConnections.end()) + { + if (iter->second.connected()) + { + iter->second.disconnect(); + } + mAvatarNameCacheConnections.erase(iter); + } + + updateListEntry(id, av_name.getCompleteName()); +} + void AnimationExplorer::requestNameCallback(LLMessageSystem* msg) { // if we weren't looking for any IDs, ignore this callback @@ -453,22 +491,27 @@ void AnimationExplorer::requestNameCallback(LLMessageSystem* msg) mRequestedIDs.erase(iter); mKnownIDs[object_id] = object_name; - S32 object_id_column = mAnimationScrollList->getColumn("object_id")->mIndex; - S32 played_by_column = mAnimationScrollList->getColumn("played_by")->mIndex; + updateListEntry(object_id, object_name); + } + } +} - // find all scroll list entries with this object UUID and update the names there - std::vector items = mAnimationScrollList->getAllData(); - for (std::vector::iterator list_iter = items.begin(); list_iter != items.end(); ++list_iter) - { - LLScrollListItem* item = *list_iter; - LLUUID list_object_id = item->getColumn(object_id_column)->getValue().asUUID(); +void AnimationExplorer::updateListEntry(const LLUUID& id, const std::string& name) +{ + S32 object_id_column = mAnimationScrollList->getColumn("object_id")->mIndex; + S32 played_by_column = mAnimationScrollList->getColumn("played_by")->mIndex; - if (object_id == list_object_id) - { - LLScrollListText* played_by_text = (LLScrollListText*)item->getColumn(played_by_column); - played_by_text->setText(object_name); - } - } + // find all scroll list entries with this object UUID and update the names there + std::vector items = mAnimationScrollList->getAllData(); + for (std::vector::iterator list_iter = items.begin(); list_iter != items.end(); ++list_iter) + { + LLScrollListItem* item = *list_iter; + LLUUID list_object_id = item->getColumn(object_id_column)->getValue().asUUID(); + + if (id == list_object_id) + { + LLScrollListText* played_by_text = (LLScrollListText*)item->getColumn(played_by_column); + played_by_text->setText(name); } } } @@ -478,7 +521,7 @@ BOOL AnimationExplorer::handleMouseDown(S32 x, S32 y, MASK mask) { if (mPreviewCtrl && mPreviewCtrl->getRect().pointInRect(x, y)) { - bringToFront( x, y ); + bringToFront(x, y); gFocusMgr.setMouseCapture(this); gViewerWindow->hideCursor(); mLastMouseX = x; diff --git a/indra/newview/animationexplorer.h b/indra/newview/animationexplorer.h index ddda69002f..f7e9bd2db2 100644 --- a/indra/newview/animationexplorer.h +++ b/indra/newview/animationexplorer.h @@ -65,6 +65,7 @@ public: // options to preview, stop animations and revoke animation permissions // -------------------------------------------------------------------------- +class LLAvatarName; class LLButton; class LLCheckBoxCtrl; class LLMessageSystem; @@ -94,6 +95,9 @@ class AnimationExplorer void requestNameCallback(LLMessageSystem* msg); // object name query callback protected: + void onAvatarNameCallback(const LLUUID& id, const LLAvatarName& av_name); + void updateListEntry(const LLUUID& id, const std::string& name); + LLScrollListCtrl* mAnimationScrollList; LLButton* mStopButton; LLButton* mRevokeButton; @@ -112,6 +116,9 @@ class AnimationExplorer std::vector mRequestedIDs; // list of object IDs we requested named for std::map mKnownIDs; // known list of names for object IDs + typedef std::map avatar_name_cache_connection_map_t; + avatar_name_cache_connection_map_t mAvatarNameCacheConnections; + void draw(); void update(); // request list update from RecentAnimationList void updateList(F64 current_timestamp); // update times and playing status in animation list diff --git a/indra/newview/app_settings/key_bindings.xml b/indra/newview/app_settings/key_bindings.xml index 18e9b97230..f3eb303b16 100644 --- a/indra/newview/app_settings/key_bindings.xml +++ b/indra/newview/app_settings/key_bindings.xml @@ -126,7 +126,6 @@ - diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index f8941bbccc..4511bb5ef8 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -8326,7 +8326,7 @@ Type String Value - http://map.secondlife.com.s3.amazonaws.com/ + https://map.secondlife.com/ CurrentMapServerURL @@ -18845,7 +18845,7 @@ Change of this parameter will affect the layout of buttons in notification toast Value 1 - PoolSizeVAssetStorage + PoolSizeAssetStorage Comment Coroutine Pool size for AssetStorage requests diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl index 57420158ca..99bcba797b 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl @@ -72,6 +72,9 @@ void main() #endif color.rgb *= vertex_color.rgb; + // Fullbright fog fix + color.rgb = fullbrightAtmosTransport(color.rgb); + color.rgb = fullbrightScaleSoftClip(color.rgb); #ifdef WATER_FOG vec3 pos = vary_position; diff --git a/indra/newview/fsareasearch.cpp b/indra/newview/fsareasearch.cpp index 6b70748d48..8f2d113217 100644 --- a/indra/newview/fsareasearch.cpp +++ b/indra/newview/fsareasearch.cpp @@ -64,6 +64,7 @@ #include "fsscrolllistctrl.h" #include "llviewermediafocus.h" #include "lltoolmgr.h" +#include "rlvhandler.h" // max number of objects that can be (de-)selected in a single packet. const S32 MAX_OBJECTS_PER_PACKET = 255; @@ -134,7 +135,7 @@ private: LLUUID mObjectID; }; -FSAreaSearch::FSAreaSearch(const LLSD& key) : +FSAreaSearch::FSAreaSearch(const LLSD& key) : LLFloater(key), mActive(false), mFilterForSale(false), @@ -162,20 +163,18 @@ FSAreaSearch::FSAreaSearch(const LLSD& key) : mExcludeChildPrims(true), mExcludeNeighborRegions(true), mRequestQueuePause(false), - mRequestNeedsSent(false) + mRequestNeedsSent(false), + mRlvBehaviorCallbackConnection() { - //TODO: Multi-floater support and get rid of the singletin. - mInstance = this; - mFactoryMap["area_search_list_panel"] = LLCallbackMap(createPanelList, this); mFactoryMap["area_search_find_panel"] = LLCallbackMap(createPanelFind, this); mFactoryMap["area_search_filter_panel"] = LLCallbackMap(createPanelFilter, this); mFactoryMap["area_search_advanced_panel"] = LLCallbackMap(createPanelAdvanced, this); mFactoryMap["area_search_options_panel"] = LLCallbackMap(createPanelOptions, this); - + // Register an idle update callback gIdleCallbacks.addFunction(idle, this); - + mParcelChangedObserver = new FSParcelChangeObserver(this); LLViewerParcelMgr::getInstance()->addObserver(mParcelChangedObserver); } @@ -187,6 +186,20 @@ FSAreaSearch::~FSAreaSearch() LL_WARNS("FSAreaSearch") << "FSAreaSearch::~FSAreaSearch() failed to delete callback" << LL_ENDL; } + if (mRlvBehaviorCallbackConnection.connected()) + { + mRlvBehaviorCallbackConnection.disconnect(); + } + + for (const auto& cb : mNameCacheConnections) + { + if (cb.second.connected()) + { + cb.second.disconnect(); + } + } + mNameCacheConnections.clear(); + if (mParcelChangedObserver) { LLViewerParcelMgr::getInstance()->removeObserver(mParcelChangedObserver); @@ -198,7 +211,7 @@ FSAreaSearch::~FSAreaSearch() BOOL FSAreaSearch::postBuild() { mTab = getChild("area_searchtab"); - + if (!gSavedSettings.getBOOL("FSAreaSearchAdvanced")) { LLPanel* advanced_tab = mTab->getPanelByName("area_search_advanced_panel"); @@ -207,7 +220,8 @@ BOOL FSAreaSearch::postBuild() mTab->removeTabPanel(advanced_tab); } } - + + mRlvBehaviorCallbackConnection = gRlvHandler.setBehaviourCallback(boost::bind(&FSAreaSearch::updateRlvRestrictions, this, _1)); return LLFloater::postBuild(); } @@ -220,7 +234,7 @@ void FSAreaSearch::onOpen(const LLSD& key) void FSAreaSearch::draw() { LLFloater::draw(); - + static LLCachedControl beacon_line_width(gSavedSettings, "DebugBeaconLineWidth"); static LLUIColor mBeaconColor = LLUIColorTable::getInstance()->getColor("AreaSearchBeaconColor"); static LLUIColor mBeaconTextColor = LLUIColorTable::getInstance()->getColor("PathfindingDefaultBeaconTextColor"); @@ -229,16 +243,13 @@ void FSAreaSearch::draw() { std::vector items = mPanelList->getResultList()->getAllData(); - for (std::vector::const_iterator item_it = items.begin(); - item_it != items.end(); - ++item_it) + for (const auto item : items) { - const LLScrollListItem* item = (*item_it); LLViewerObject* objectp = gObjectList.findObject(item->getUUID()); if (objectp) { - const std::string &objectName = mObjectDetails[item->getUUID()].description; + const std::string& objectName = mObjectDetails[item->getUUID()].description; gObjectList.addDebugBeacon(objectp->getPositionAgent(), objectName, mBeaconColor, mBeaconTextColor, beacon_line_width); } } @@ -293,9 +304,17 @@ void* FSAreaSearch::createPanelOptions(void* data) return self->mPanelOptions; } +void FSAreaSearch::updateRlvRestrictions(ERlvBehaviour behavior) +{ + if (behavior == RLV_BHVR_SHOWNAMES) + { + refreshList(false); + } +} + void FSAreaSearch::checkRegion() { - if (mInstance && mActive) + if (mActive) { // Check if we changed region, and if we did, clear the object details cache. LLViewerRegion* region = gAgent.getRegion(); // getRegion can return NULL if disconnected. @@ -305,7 +324,7 @@ void FSAreaSearch::checkRegion() { std::vector uniqueRegions; region->getNeighboringRegions(uniqueRegions); - if(std::find(uniqueRegions.begin(), uniqueRegions.end(), mLastRegion) != uniqueRegions.end()) + if (std::find(uniqueRegions.begin(), uniqueRegions.end(), mLastRegion) != uniqueRegions.end()) { // Crossed into a neighboring region, no need to clear everything. mLastRegion = region; @@ -339,11 +358,9 @@ void FSAreaSearch::refreshList(bool cache_clear) } else { - for (std::map::iterator object_it = mObjectDetails.begin(); - object_it != mObjectDetails.end(); - ++object_it) + for (auto& object_it : mObjectDetails) { - object_it->second.listed = false; + object_it.second.listed = false; } } mPanelList->getResultList()->deleteAllItems(); @@ -361,16 +378,16 @@ void FSAreaSearch::findObjects() { return; } - + LLViewerRegion* our_region = gAgent.getRegion(); if (!our_region) { // Got disconnected or is in the middle of a teleport. return; } - + LL_DEBUGS("FSAreaSearch_spammy") << "Doing a FSAreaSearch::findObjects" << LL_ENDL; - + mLastUpdateTimer.stop(); // stop sets getElapsedTimeF32() time to zero. // Pause processing of requestqueue until done adding new requests. mRequestQueuePause = true; @@ -381,13 +398,13 @@ void FSAreaSearch::findObjects() for (S32 i = 0; i < object_count; i++) { - LLViewerObject *objectp = gObjectList.getObject(i); - if (!(objectp && isSearchableObject(objectp, our_region))) + LLViewerObject* objectp = gObjectList.getObject(i); + if (!objectp || !isSearchableObject(objectp, our_region)) { continue; } - LLUUID object_id = objectp->getID(); + const LLUUID& object_id = objectp->getID(); if (object_id.isNull()) { @@ -430,17 +447,15 @@ void FSAreaSearch::findObjects() S32 request_count = 0; // requests for non-existent objects will never arrive, check and update the queue. - for (std::map::iterator object_it = mObjectDetails.begin(); - object_it != mObjectDetails.end(); - ++object_it) + for (auto& object_it : mObjectDetails) { - if (object_it->second.request == FSObjectProperties::NEED || object_it->second.request == FSObjectProperties::SENT) + if (object_it.second.request == FSObjectProperties::NEED || object_it.second.request == FSObjectProperties::SENT) { - LLUUID id = object_it->second.id; + const LLUUID& id = object_it.second.id; LLViewerObject* objectp = gObjectList.findObject(id); if (!objectp) { - object_it->second.request = FSObjectProperties::FAILED; + object_it.second.request = FSObjectProperties::FAILED; mRequested--; } else @@ -449,10 +464,10 @@ void FSAreaSearch::findObjects() } } } - + if (mRequested != request_count) { - LL_DEBUGS("FSAreaSearch") << "Requested mismatch: " << request_count << " actual vs. " << mRequested << LL_ENDL; + LL_DEBUGS("FSAreaSearch") << "Requested mismatch: " << request_count << " actual vs. " << mRequested << LL_ENDL; mRequested = request_count; } @@ -486,7 +501,7 @@ bool FSAreaSearch::isSearchableObject(LLViewerObject* objectp, LLViewerRegion* o { return false; } - + //----------------------------------------------------------------------- // Excludes //----------------------------------------------------------------------- @@ -523,7 +538,7 @@ void FSAreaSearch::processRequestQueue() { if (!mActive || mRequestQueuePause) { - return; + return; } if (mLastPropertiesReceivedTimer.getElapsedTimeF32() > REQUEST_TIMEOUT) @@ -531,18 +546,16 @@ void FSAreaSearch::processRequestQueue() LL_DEBUGS("FSAreaSearch") << "Timeout reached, resending requests."<< LL_ENDL; S32 request_count = 0; S32 failed_count = 0; - for (std::map::iterator object_it = mObjectDetails.begin(); - object_it != mObjectDetails.end(); - ++object_it) + for (auto& object_it : mObjectDetails) { - if (object_it->second.request == FSObjectProperties::SENT) + if (object_it.second.request == FSObjectProperties::SENT) { - object_it->second.request = FSObjectProperties::NEED; + object_it.second.request = FSObjectProperties::NEED; mRequestNeedsSent = true; request_count++; } - if (object_it->second.request == FSObjectProperties::FAILED) + if (object_it.second.request == FSObjectProperties::FAILED) { failed_count++; } @@ -565,32 +578,28 @@ void FSAreaSearch::processRequestQueue() if (!mRequestNeedsSent) { - return; + return; } mRequestNeedsSent = false; - for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); - iter != LLWorld::getInstance()->getRegionList().end(); ++iter) + for (const auto regionp : LLWorld::getInstance()->getRegionList()) { - LLViewerRegion* regionp = *iter; U64 region_handle = regionp->getHandle(); if (mRegionRequests[region_handle] > (MAX_OBJECTS_PER_PACKET + 128)) { mRequestNeedsSent = true; return; } - + std::vector request_list; bool need_continue = false; - - for (std::map::iterator object_it = mObjectDetails.begin(); - object_it != mObjectDetails.end(); - ++object_it) + + for (auto& object_it : mObjectDetails) { - if (object_it->second.request == FSObjectProperties::NEED && object_it->second.region_handle == region_handle) + if (object_it.second.request == FSObjectProperties::NEED && object_it.second.region_handle == region_handle) { - request_list.push_back(object_it->second.local_id); - object_it->second.request = FSObjectProperties::SENT; + request_list.push_back(object_it.second.local_id); + object_it.second.request = FSObjectProperties::SENT; mRegionRequests[region_handle]++; if (mRegionRequests[region_handle] >= ((MAX_OBJECTS_PER_PACKET * 3) - 3)) { @@ -621,9 +630,8 @@ void FSAreaSearch::requestObjectProperties(const std::vector& request_list, bool start_new_message = true; S32 select_count = 0; LLMessageSystem* msg = gMessageSystem; - - for (std::vector::const_iterator iter = request_list.begin(); - iter != request_list.end(); ++iter) + + for (const auto& id : request_list) { if (start_new_message) { @@ -641,12 +649,12 @@ void FSAreaSearch::requestObjectProperties(const std::vector& request_list, select_count++; start_new_message = false; } - + msg->nextBlockFast(_PREHASH_ObjectData); - msg->addU32Fast(_PREHASH_ObjectLocalID, (*iter) ); + msg->addU32Fast(_PREHASH_ObjectLocalID, id); select_count++; - - if(msg->isSendFull(NULL) || select_count >= MAX_OBJECTS_PER_PACKET) + + if (msg->isSendFull(NULL) || select_count >= MAX_OBJECTS_PER_PACKET) { LL_DEBUGS("FSAreaSearch") << "Sent one full " << (select ? "ObjectSelect" : "ObjectDeselect") << " message with " << select_count << " object data blocks." << LL_ENDL; msg->sendReliable(regionp->getHost()); @@ -664,10 +672,9 @@ void FSAreaSearch::requestObjectProperties(const std::vector& request_list, void FSAreaSearch::processObjectProperties(LLMessageSystem* msg) { - // This function is called by llviewermessage even if no floater has been created. - if (!(mInstance && mActive)) + if (!mActive) { - return; + return; } LLViewerRegion* our_region = gAgent.getRegion(); @@ -781,21 +788,21 @@ void FSAreaSearch::matchObject(FSObjectProperties& details, LLViewerObject* obje //----------------------------------------------------------------------- // Filters //----------------------------------------------------------------------- - + if (mFilterForSale && !(details.sale_info.isForSale() && (details.sale_info.getSalePrice() >= mFilterForSaleMin && details.sale_info.getSalePrice() <= mFilterForSaleMax))) { return; } - + if (mFilterDistance) { S32 distance = (S32)calculateObjectDistance(mPanelList->getAgentLastPosition(), objectp);// used mAgentLastPosition instead of gAgent->getPositionGlobal for performace - if (!(distance >= mFilterDistanceMin && distance <= mFilterDistanceMax)) + if (distance < mFilterDistanceMin || distance > mFilterDistanceMax) { return; } } - + if (mFilterClickAction) { switch(mFilterClickActionType) @@ -814,7 +821,7 @@ void FSAreaSearch::matchObject(FSObjectProperties& details, LLViewerObject* obje return; } break; - default: // all other mouse click action types + default: // all other mouse click action types if ((mFilterClickActionType - 2) != objectp->getClickAction()) { return; @@ -822,15 +829,6 @@ void FSAreaSearch::matchObject(FSObjectProperties& details, LLViewerObject* obje break; } } - - //TODO: texture id search -// for (uuid_vec_t::const_iterator texture_it = details.texture_ids.begin(); -// texture_it != details.texture_ids.end(); ++texture_it) -// { -// if ( "" == (*texture_it).asString()) -// { -// } -// } if (mFilterPhysical && !objectp->flagUsePhysics()) { @@ -841,36 +839,36 @@ void FSAreaSearch::matchObject(FSObjectProperties& details, LLViewerObject* obje { return; } - + if (mFilterLocked && (details.owner_mask & PERM_MOVE)) { return; } - + if (mFilterPhantom && !objectp->flagPhantom()) { return; } - + if (mFilterAttachment && !objectp->isAttachment()) { return; } - + if (mFilterMoaP) { bool moap = false; U8 texture_count = objectp->getNumTEs(); - for(U8 i = 0; i < texture_count; i++) + for (U8 i = 0; i < texture_count; i++) { - if(objectp->getTE(i)->hasMedia()) + if (objectp->getTE(i)->hasMedia()) { moap = true; break; } } - if(!moap) + if (!moap) { return; } @@ -909,10 +907,10 @@ void FSAreaSearch::matchObject(FSObjectProperties& details, LLViewerObject* obje std::string object_description = details.description; details.name_requested = false; - getNameFromUUID(details.ownership_id, owner_name, details.group_owned, details.name_requested); - getNameFromUUID(details.creator_id, creator_name, false, details.name_requested); - getNameFromUUID(details.last_owner_id, last_owner_name, false, details.name_requested); - getNameFromUUID(details.group_id, group_name, true, details.name_requested); + getNameFromUUID(details.ownership_id, true, owner_name, details.group_owned, details.name_requested); + getNameFromUUID(details.creator_id, false, creator_name, false, details.name_requested); + getNameFromUUID(details.last_owner_id, false, last_owner_name, false, details.name_requested); + getNameFromUUID(details.group_id, false, group_name, true, details.name_requested); if (mRegexSearch) { @@ -991,7 +989,7 @@ void FSAreaSearch::matchObject(FSObjectProperties& details, LLViewerObject* obje //----------------------------------------------------------------------- // Object passed all above tests, add it to the List tab. //----------------------------------------------------------------------- - + details.listed = true; LLScrollListCell::Params cell_params; @@ -1083,15 +1081,13 @@ void FSAreaSearch::matchObject(FSObjectProperties& details, LLViewerObject* obje mPanelList->getResultList()->refreshLineHeight(); } -// Allows the object costs to be updated on-the-fly so as to bypass the problem with the data being stale when first accessed. void FSAreaSearch::updateObjectCosts(const LLUUID& object_id, F32 object_cost, F32 link_cost, F32 physics_cost, F32 link_physics_cost) { - // This fuction is called by LLObjectCostResponder::result even if no floater has been created. - if (!(mInstance && mActive)) + if (!mActive) { return; } - + FSScrollListCtrl* result_list = mPanelList->getResultList(); if (result_list) { @@ -1107,20 +1103,23 @@ void FSAreaSearch::updateObjectCosts(const LLUUID& object_id, F32 object_cost, F } } } - } -void FSAreaSearch::getNameFromUUID(LLUUID& id, std::string& name, BOOL group, bool& name_requested) +void FSAreaSearch::getNameFromUUID(const LLUUID& id, bool needs_rlva_check, std::string& name, bool group, bool& name_requested) { + static const std::string unknown_name = LLTrans::getString("AvatarNameWaiting"); + if (group) { BOOL is_group; - if(!gCacheName->getIfThere(id, name, is_group)) + if (!gCacheName->getIfThere(id, name, is_group)) { - if(std::find(mNamesRequested.begin(), mNamesRequested.end(), id) == mNamesRequested.end()) + name = unknown_name; + if (std::find(mNamesRequested.begin(), mNamesRequested.end(), id) == mNamesRequested.end()) { mNamesRequested.push_back(id); - gCacheName->get(id, group, boost::bind(&FSAreaSearch::callbackLoadFullName, this, _1, _2)); + boost::signals2::connection cb_connection = gCacheName->get(id, group, boost::bind(&FSAreaSearch::callbackLoadFullName, this, _1, _2)); + mNameCacheConnections.insert(std::make_pair(id, cb_connection)); // mNamesRequested will do the dupe check } name_requested = true; } @@ -1130,44 +1129,70 @@ void FSAreaSearch::getNameFromUUID(LLUUID& id, std::string& name, BOOL group, bo LLAvatarName av_name; if (LLAvatarNameCache::get(id, &av_name)) { - name = av_name.getUserName(); + if (!needs_rlva_check || !gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) + { + name = av_name.getCompleteName(); + } + else + { + name = RlvStrings::getAnonym(av_name); + } } else { - if(std::find(mNamesRequested.begin(), mNamesRequested.end(), id) == mNamesRequested.end()) + name = unknown_name; + if (std::find(mNamesRequested.begin(), mNamesRequested.end(), id) == mNamesRequested.end()) { mNamesRequested.push_back(id); - LLAvatarNameCache::get(id, boost::bind(&FSAreaSearch::avatarNameCacheCallback, this, _1, _2)); + boost::signals2::connection cb_connection = LLAvatarNameCache::get(id, boost::bind(&FSAreaSearch::avatarNameCacheCallback, this, _1, _2, needs_rlva_check)); + mNameCacheConnections.insert(std::make_pair(id, cb_connection)); // mNamesRequested will do the dupe check } name_requested = true; } } } -void FSAreaSearch::avatarNameCacheCallback(const LLUUID& id, const LLAvatarName& av_name) +void FSAreaSearch::avatarNameCacheCallback(const LLUUID& id, const LLAvatarName& av_name, bool needs_rlva_check) { - callbackLoadFullName(id, av_name.getUserName()); + std::string name; + if (!needs_rlva_check || !gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) + { + name = av_name.getCompleteName(); + } + else + { + name = RlvStrings::getAnonym(av_name); + } + callbackLoadFullName(id, name); } void FSAreaSearch::callbackLoadFullName(const LLUUID& id, const std::string& full_name) { - LLViewerRegion* our_region = gAgent.getRegion(); - - for (std::map::iterator object_it = mObjectDetails.begin(); - object_it != mObjectDetails.end(); - ++object_it) + auto iter = mNameCacheConnections.find(id); + if (iter != mNameCacheConnections.end()) { - if (object_it->second.name_requested && !object_it->second.listed) + if (iter->second.connected()) { - LLUUID object_id = object_it->second.id; + iter->second.disconnect(); + } + mNameCacheConnections.erase(iter); + } + + LLViewerRegion* our_region = gAgent.getRegion(); + + for (auto& entry : mObjectDetails) + { + if (entry.second.name_requested && !entry.second.listed) + { + const LLUUID& object_id = entry.second.id; LLViewerObject* objectp = gObjectList.findObject(object_id); if (objectp && isSearchableObject(objectp, our_region)) { - matchObject(object_it->second, objectp); + matchObject(entry.second, objectp); } } } - + mPanelList->updateName(id, full_name); } @@ -1272,7 +1297,7 @@ bool FSAreaSearch::regexTest(std::string text) // boost::regex pattern("[\\w]{8}-[\\w]{4}-[\\w]{4}-[\\w]{4}-[\\w]{12}"); // [\p{XDigit}]{8}(-[\p{XDigit}]{4}){3}-[\p{XDigit}]{12} // to find all objects that don't belong to a group, use (?!^Name of the group$).* in the group field. - + try { std::string test_text = "asdfghjklqwerty1234567890"; @@ -1420,12 +1445,16 @@ void FSPanelAreaSearchList::setCounterText(LLStringUtil::format_map_t args) void FSPanelAreaSearchList::onDoubleClick() { - LLScrollListItem *item = mResultList->getFirstSelected(); - if (!item) return; - LLUUID object_id = item->getUUID(); + LLScrollListItem* item = mResultList->getFirstSelected(); + if (!item) + { + return; + } + + const LLUUID& object_id = item->getUUID(); LLViewerObject* objectp = gObjectList.findObject(object_id); if (objectp) - { + { FSObjectProperties& details = mFSAreaSearch->mObjectDetails[object_id]; LLTracker::trackLocation(objectp->getPositionGlobal(), details.name, "", LLTracker::LOCATION_ITEM); @@ -1450,7 +1479,7 @@ void FSPanelAreaSearchList::updateScrollList() { bool agent_moved = false; const LLVector3d current_agent_position = gAgent.getPositionGlobal(); - + if (dist_vec(mAgentLastPosition, current_agent_position) > MIN_DISTANCE_MOVED) { agent_moved = true; @@ -1463,15 +1492,12 @@ void FSPanelAreaSearchList::updateScrollList() // Iterate over the rows in the list, deleting ones whose object has gone away. std::vector items = mResultList->getAllData(); - for (std::vector::iterator item_it = items.begin(); - item_it != items.end(); - ++item_it) + for (const auto item : items) { - LLScrollListItem* item = (*item_it); - LLUUID row_id = item->getUUID(); + const LLUUID& row_id = item->getUUID(); LLViewerObject* objectp = gObjectList.findObject(row_id); - - if ((!objectp) || (!mFSAreaSearch->isSearchableObject(objectp, our_region))) + + if (!objectp || !mFSAreaSearch->isSearchableObject(objectp, our_region)) { // This item's object has been deleted -- remove the row. // Removing the row won't throw off our iteration, since we have a local copy of the array. @@ -1502,15 +1528,12 @@ void FSPanelAreaSearchList::updateResultListColumns() std::vector column_params = mResultList->getColumnInitParams(); std::string current_sort_col = mResultList->getSortColumnName(); BOOL current_sort_asc = mResultList->getSortAscending(); - + mResultList->clearColumns(); mResultList->updateLayout(); - std::vector::iterator param_it; - for (param_it = column_params.begin(); param_it != column_params.end(); ++param_it) + for (const auto& p : column_params) { - LLScrollListColumn::Params p = *param_it; - LLScrollListColumn::Params params; params.header = p.header; params.name = p.name; @@ -1538,7 +1561,7 @@ void FSPanelAreaSearchList::updateResultListColumns() void FSPanelAreaSearchList::onColumnVisibilityChecked(const LLSD& userdata) { - std::string column = userdata.asString(); + const std::string& column = userdata.asStringRef(); U32 column_config = gSavedSettings.getU32("FSAreaSearchColumnConfig"); U32 new_value; @@ -1559,28 +1582,25 @@ void FSPanelAreaSearchList::onColumnVisibilityChecked(const LLSD& userdata) bool FSPanelAreaSearchList::onEnableColumnVisibilityChecked(const LLSD& userdata) { - std::string column = userdata.asString(); + const std::string& column = userdata.asStringRef(); U32 column_config = gSavedSettings.getU32("FSAreaSearchColumnConfig"); return (mColumnBits[column] & column_config); } -void FSPanelAreaSearchList::updateName(LLUUID id, std::string name) +void FSPanelAreaSearchList::updateName(const LLUUID& id, const std::string& name) { LLScrollListColumn* creator_column = mResultList->getColumn("creator"); LLScrollListColumn* owner_column = mResultList->getColumn("owner"); LLScrollListColumn* group_column = mResultList->getColumn("group"); LLScrollListColumn* last_owner_column = mResultList->getColumn("last_owner"); - + // Iterate over the rows in the list, updating the ones with matching id. std::vector items = mResultList->getAllData(); - for (std::vector::iterator item_it = items.begin(); - item_it != items.end(); - ++item_it) + for (const auto item : items) { - LLScrollListItem* item = (*item_it); - LLUUID row_id = item->getUUID(); + const LLUUID& row_id = item->getUUID(); FSObjectProperties& details = mFSAreaSearch->mObjectDetails[row_id]; if (creator_column && (id == details.creator_id)) @@ -1615,7 +1635,7 @@ void FSPanelAreaSearchList::updateName(LLUUID id, std::string name) bool FSPanelAreaSearchList::onContextMenuItemEnable(const LLSD& userdata) { - std::string parameter = userdata.asString(); + const std::string& parameter = userdata.asStringRef(); if (parameter == "one") { // return true if just one item is selected. @@ -1626,7 +1646,7 @@ bool FSPanelAreaSearchList::onContextMenuItemEnable(const LLSD& userdata) // return true if the object is within the draw distance. if (mResultList->getNumSelected() == 1) { - LLUUID object_id = mResultList->getFirstSelected()->getUUID(); + const LLUUID& object_id = mResultList->getFirstSelected()->getUUID(); LLViewerObject* objectp = gObjectList.findObject(object_id); return (objectp && calculateObjectDistance(gAgent.getPositionGlobal(), objectp) < gAgentCamera.mDrawDistance); } @@ -1648,7 +1668,7 @@ bool FSPanelAreaSearchList::onContextMenuItemEnable(const LLSD& userdata) bool FSPanelAreaSearchList::onContextMenuItemClick(const LLSD& userdata) { - std::string action = userdata.asString(); + const std::string& action = userdata.asStringRef(); LL_DEBUGS("FSAreaSearch") << "Right click menu " << action << " was selected." << LL_ENDL; if (action == "select_all") @@ -1681,23 +1701,22 @@ bool FSPanelAreaSearchList::onContextMenuItemClick(const LLSD& userdata) std::vector selected = mResultList->getAllSelected(); S32 cnt = 0; - for(std::vector::iterator item_it = selected.begin(); - item_it != selected.end(); ++item_it) + for (const auto item : selected) { switch (c) { case 't': // touch { - new FSAreaSearchTouchTimer((*item_it)->getUUID(), cnt * 0.2f); + new FSAreaSearchTouchTimer(item->getUUID(), cnt * 0.2f); cnt++; } break; case 's': // script - FSLSLBridge::instance().viewerToLSL("getScriptInfo|" + (*item_it)->getUUID().asString() + "|" + (gSavedSettings.getBOOL("FSScriptInfoExtended") ? "1" : "0")); + FSLSLBridge::instance().viewerToLSL("getScriptInfo|" + item->getUUID().asString() + "|" + (gSavedSettings.getBOOL("FSScriptInfoExtended") ? "1" : "0")); break; case 'l': // blacklist { - LLUUID object_id = (*item_it)->getUUID(); + const LLUUID& object_id = item->getUUID(); LLViewerObject* objectp = gObjectList.findObject(object_id); // if (objectp) // [RLVa:KB] - Checked: RLVa-2.0.0 | FS-specific @@ -1745,7 +1764,7 @@ bool FSPanelAreaSearchList::onContextMenuItemClick(const LLSD& userdata) { if (mResultList->getNumSelected() == 1) { - LLUUID object_id = mResultList->getFirstSelected()->getUUID(); + const LLUUID& object_id = mResultList->getFirstSelected()->getUUID(); LLViewerObject* objectp = gObjectList.findObject(object_id); if (objectp) { @@ -1821,7 +1840,6 @@ bool FSPanelAreaSearchList::onContextMenuItemClick(const LLSD& userdata) distance += depth * 0.5; - // Verify that the bounding box isn't inside the near clip. Using OBB-plane intersection to check if the // near-clip plane intersects with the bounding box, and if it does, adjust the distance such that the // object doesn't clip. @@ -1839,7 +1857,6 @@ bool FSPanelAreaSearchList::onContextMenuItemClick(const LLSD& userdata) distance = min_camera_dist; } - LLVector3d camera_pos(target_pos + camera_dir * distance); if (camera_dir == LLVector3d::z_axis || camera_dir == LLVector3d::z_axis_neg) @@ -1889,23 +1906,26 @@ bool FSPanelAreaSearchList::onContextMenuItemClick(const LLSD& userdata) LLSelectMgr::getInstance()->deselectAll(); std::vector selected = mResultList->getAllSelected(); - for(std::vector::iterator item_it = selected.begin(); - item_it != selected.end(); ++item_it) + for (const auto item : selected) { - LLUUID object_id = (*item_it)->getUUID(); + const LLUUID& object_id = item->getUUID(); LLViewerObject* objectp = gObjectList.findObject(object_id); if (objectp) { LLSelectMgr::getInstance()->selectObjectAndFamily(objectp); - if ( c == 'r' ) + if (c == 'r') { // need to set permissions for object return LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->findNode(objectp); - if( !node ) + if (!node) + { break; + } - if( !mFSAreaSearch || mFSAreaSearch->mObjectDetails.end() == mFSAreaSearch->mObjectDetails.find(object_id ) ) + if (!mFSAreaSearch || mFSAreaSearch->mObjectDetails.end() == mFSAreaSearch->mObjectDetails.find(object_id)) + { break; + } FSObjectProperties& details = mFSAreaSearch->mObjectDetails[object_id]; node->mValid = TRUE; @@ -1961,7 +1981,7 @@ void FSPanelAreaSearchList::buyObject(FSObjectProperties& details, LLViewerObjec LLSelectMgr::getInstance()->deselectAll(); LLSelectMgr::getInstance()->selectObjectAndFamily(objectp); LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->findNode(objectp); - + if (node) { node->mValid = TRUE; @@ -1985,26 +2005,25 @@ void FSPanelAreaSearchList::sitOnObject(FSObjectProperties& details, LLViewerObj { if ( (!RlvActions::isRlvEnabled()) || (RlvActions::canSit(objectp)) ) { - LLSelectMgr::getInstance()->deselectAll(); - LLSelectMgr::getInstance()->selectObjectAndFamily(objectp); - LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->findNode(objectp); - if (node) - { - gMessageSystem->newMessageFast(_PREHASH_AgentRequestSit); - gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgentID); - gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgentSessionID); - gMessageSystem->nextBlockFast(_PREHASH_TargetObject); - gMessageSystem->addUUIDFast(_PREHASH_TargetID, objectp->mID); - gMessageSystem->addVector3Fast(_PREHASH_Offset, LLVector3::zero); - objectp->getRegion()->sendReliableMessage(); - } - else - { - LL_WARNS("FSAreaSearch") << "No LLSelectNode node" << LL_ENDL; - } - } - + LLSelectMgr::getInstance()->deselectAll(); + LLSelectMgr::getInstance()->selectObjectAndFamily(objectp); + LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->findNode(objectp); + if (node) + { + gMessageSystem->newMessageFast(_PREHASH_AgentRequestSit); + gMessageSystem->nextBlockFast(_PREHASH_AgentData); + gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgentID); + gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgentSessionID); + gMessageSystem->nextBlockFast(_PREHASH_TargetObject); + gMessageSystem->addUUIDFast(_PREHASH_TargetID, objectp->mID); + gMessageSystem->addVector3Fast(_PREHASH_Offset, LLVector3::zero); + objectp->getRegion()->sendReliableMessage(); + } + else + { + LL_WARNS("FSAreaSearch") << "No LLSelectNode node" << LL_ENDL; + } + } } //--------------------------------------------------------------------------- @@ -2067,7 +2086,7 @@ void FSPanelAreaSearchFind::onButtonClickedClear() // handle the "enter" key BOOL FSPanelAreaSearchFind::handleKeyHere(KEY key, MASK mask) { - if( KEY_RETURN == key ) + if (KEY_RETURN == key) { mFSAreaSearch->onButtonClickedSearch(); return TRUE; @@ -2091,18 +2110,18 @@ BOOL FSPanelAreaSearchFilter::postBuild() { mCheckboxLocked = getChild("filter_locked"); mCheckboxLocked->setCommitCallback(boost::bind(&FSPanelAreaSearchFilter::onCommitCheckbox, this)); - + mCheckboxPhysical = getChild("filter_physical"); mCheckboxPhysical->setEnabled(FALSE); mCheckboxPhysical->setCommitCallback(boost::bind(&FSPanelAreaSearchFilter::onCommitCheckbox, this)); - + mCheckboxTemporary = getChild("filter_temporary"); mCheckboxTemporary->setEnabled(FALSE); mCheckboxTemporary->setCommitCallback(boost::bind(&FSPanelAreaSearchFilter::onCommitCheckbox, this)); mCheckboxPhantom = getChild("filter_phantom"); mCheckboxPhantom->setCommitCallback(boost::bind(&FSPanelAreaSearchFilter::onCommitCheckbox, this)); - + mCheckboxForSale = getChild("filter_for_sale"); mCheckboxForSale->setCommitCallback(boost::bind(&FSPanelAreaSearchFilter::onCommitCheckbox, this)); @@ -2122,47 +2141,47 @@ BOOL FSPanelAreaSearchFilter::postBuild() mCheckboxExcludeAttachment = getChild("exclude_attachment"); mCheckboxExcludeAttachment->set(TRUE); mCheckboxExcludeAttachment->setCommitCallback(boost::bind(&FSPanelAreaSearchFilter::onCommitCheckbox, this)); - + mCheckboxExcludePhysics = getChild("exclude_physical"); mCheckboxExcludePhysics->set(TRUE); mCheckboxExcludePhysics->setCommitCallback(boost::bind(&FSPanelAreaSearchFilter::onCommitCheckbox, this)); - + mCheckboxExcludetemporary = getChild("exclude_temporary"); mCheckboxExcludetemporary->set(TRUE); mCheckboxExcludetemporary->setCommitCallback(boost::bind(&FSPanelAreaSearchFilter::onCommitCheckbox, this)); - + mCheckboxExcludeChildPrim = getChild("exclude_childprim"); mCheckboxExcludeChildPrim->set(TRUE); mCheckboxExcludeChildPrim->setCommitCallback(boost::bind(&FSPanelAreaSearchFilter::onCommitCheckbox, this)); - + mCheckboxExcludeNeighborRegions = getChild("exclude_neighbor_region"); mCheckboxExcludeNeighborRegions->set(TRUE); mCheckboxExcludeNeighborRegions->setCommitCallback(boost::bind(&FSPanelAreaSearchFilter::onCommitCheckbox, this)); mButtonApply = getChild("apply"); mButtonApply->setClickedCallback(boost::bind(&FSAreaSearch::onButtonClickedSearch, mFSAreaSearch)); - + mCheckboxDistance = getChild("filter_distance"); mCheckboxDistance->setCommitCallback(boost::bind(&FSPanelAreaSearchFilter::onCommitCheckbox, this)); mSpinDistanceMinValue = getChild("min_distance"); mSpinDistanceMinValue->setCommitCallback(boost::bind(&FSPanelAreaSearchFilter::onCommitSpin, this)); - + mSpinDistanceMaxValue= getChild("max_distance"); mSpinDistanceMaxValue->setCommitCallback(boost::bind(&FSPanelAreaSearchFilter::onCommitSpin, this)); - + mCheckboxMoaP = getChild("filter_moap"); mCheckboxMoaP->setCommitCallback(boost::bind(&FSPanelAreaSearchFilter::onCommitCheckbox, this)); - + mCheckboxPermCopy = getChild("filter_perm_copy"); mCheckboxPermCopy->setCommitCallback(boost::bind(&FSPanelAreaSearchFilter::onCommitCheckbox, this)); - + mCheckboxPermModify = getChild("filter_perm_modify"); mCheckboxPermModify->setCommitCallback(boost::bind(&FSPanelAreaSearchFilter::onCommitCheckbox, this)); - + mCheckboxPermTransfer = getChild("filter_perm_transfer"); mCheckboxPermTransfer->setCommitCallback(boost::bind(&FSPanelAreaSearchFilter::onCommitCheckbox, this)); - + mCheckboxAgentParcelOnly = getChild("filter_agent_parcel_only"); mCheckboxAgentParcelOnly->setCommitCallback(boost::bind(&FSPanelAreaSearchFilter::onCommitCheckbox, this)); @@ -2275,7 +2294,7 @@ FSPanelAreaSearchOptions::~FSPanelAreaSearchOptions() void FSPanelAreaSearchOptions::onCommitCheckboxDisplayColumn(const LLSD& userdata) { - std::string column_name = userdata.asString(); + const std::string& column_name = userdata.asStringRef(); if (column_name.empty()) { LL_WARNS("FSAreaSearch") << "Missing action text." << LL_ENDL; @@ -2312,4 +2331,3 @@ BOOL FSPanelAreaSearchAdvanced::postBuild() // virtual FSPanelAreaSearchAdvanced::~FSPanelAreaSearchAdvanced() { } - diff --git a/indra/newview/fsareasearch.h b/indra/newview/fsareasearch.h index 2e3d82f938..00c8e36444 100644 --- a/indra/newview/fsareasearch.h +++ b/indra/newview/fsareasearch.h @@ -28,14 +28,15 @@ #ifndef FS_AREASEARCH_H #define FS_AREASEARCH_H +#include "llcategory.h" #include "llfloater.h" #include "llframetimer.h" -#include "llsaleinfo.h" -#include "llcategory.h" #include "llpermissions.h" -#include "llviewerobject.h" -#include +#include "llsaleinfo.h" #include "llscrolllistcolumn.h" +#include "llviewerobject.h" +#include "rlvdefines.h" +#include class LLAvatarName; class LLTextBox; @@ -113,7 +114,7 @@ public: virtual void draw(); virtual void onOpen(const LLSD& key); - void avatarNameCacheCallback(const LLUUID& id, const LLAvatarName& av_name); + void avatarNameCacheCallback(const LLUUID& id, const LLAvatarName& av_name, bool needs_rlva_check); void callbackLoadFullName(const LLUUID& id, const std::string& full_name); void processObjectProperties(LLMessageSystem* msg); void updateObjectCosts(const LLUUID& object_id, F32 object_cost, F32 link_cost, F32 physics_cost, F32 link_physics_cost); @@ -171,13 +172,16 @@ public: private: void requestObjectProperties(const std::vector< U32 >& request_list, bool select, LLViewerRegion* regionp); void matchObject(FSObjectProperties& details, LLViewerObject* objectp); - void getNameFromUUID(LLUUID& id, std::string& name, BOOL group, bool& name_requested); + void getNameFromUUID(const LLUUID& id, bool needs_rvla_check, std::string& name, bool group, bool& name_requested); void updateCounterText(); bool regexTest(std::string text); void findObjects(); void processRequestQueue(); + boost::signals2::connection mRlvBehaviorCallbackConnection; + void updateRlvRestrictions(ERlvBehaviour behavior); + S32 mRequested; bool mRefresh; S32 mSearchableObjects; @@ -206,16 +210,15 @@ private: uuid_vec_t mNamesRequested; + typedef std::map name_cache_connection_map_t; + name_cache_connection_map_t mNameCacheConnections; + LLViewerRegion* mLastRegion; class FSParcelChangeObserver; friend class FSParcelChangeObserver; FSParcelChangeObserver* mParcelChangedObserver; - // Used for checking to see if a floater has been created. - // Can not be trusted as a singleton pointer, don't use as a pointer. - FSAreaSearch* mInstance; - LLTabContainer* mTab; FSPanelAreaSearchList* mPanelList; FSPanelAreaSearchFind* mPanelFind; @@ -284,7 +287,7 @@ public: void setCounterText(); void setCounterText(LLStringUtil::format_map_t args); void updateScrollList(); - void updateName(LLUUID id, std::string name); + void updateName(const LLUUID& id, const std::string& name); static void touchObject(LLViewerObject* objectp); FSScrollListCtrl* getResultList() { return mResultList; } @@ -409,9 +412,6 @@ public: FSPanelAreaSearchOptions(FSAreaSearch* pointer); virtual ~FSPanelAreaSearchOptions(); - // not used -// /*virtual*/ BOOL postBuild(); - private: void onCommitCheckboxDisplayColumn(const LLSD& userdata); bool onEnableColumnVisibilityChecked(const LLSD& userdata); diff --git a/indra/newview/fsfloatersearch.cpp b/indra/newview/fsfloatersearch.cpp index d921697fe5..fd5e39d3a7 100644 --- a/indra/newview/fsfloatersearch.cpp +++ b/indra/newview/fsfloatersearch.cpp @@ -729,11 +729,16 @@ FSPanelSearchPeople::FSPanelSearchPeople() : FSSearchPanelBase() , mStartSearch(0) , mResultsReceived(0) , mResultsContent() +, mAvatarNameCallbackConnection() { } FSPanelSearchPeople::~FSPanelSearchPeople() { + if (mAvatarNameCallbackConnection.connected()) + { + mAvatarNameCallbackConnection.disconnect(); + } } BOOL FSPanelSearchPeople::postBuild() @@ -776,6 +781,24 @@ void FSPanelSearchPeople::find() return; } + if (LLUUID::validate(text)) + { + LLUUID id(text); + + mSearchResults->deleteAllItems(); + mSearchResults->setCommentText(LLTrans::getString("searching")); + mResultsReceived = 0; + mNumResultsReturned = 0; + + if (mAvatarNameCallbackConnection.connected()) + { + mAvatarNameCallbackConnection.disconnect(); + } + mAvatarNameCallbackConnection = LLAvatarNameCache::get(id, boost::bind(&FSPanelSearchPeople::onAvatarNameCallback, this, _1, _2)); + + return; + } + LLStringUtil::replaceChar(text, '.', ' '); mResultsReceived = 0; @@ -784,7 +807,7 @@ void FSPanelSearchPeople::find() mQueryID.setNull(); } mQueryID.generate(); - + if (mStartSearch < 0) { mStartSearch = 0; @@ -996,6 +1019,50 @@ void FSPanelSearchPeople::processSearchReply(LLMessageSystem* msg, void**) } } +void FSPanelSearchPeople::onAvatarNameCallback(const LLUUID& id, const LLAvatarName& av_name) +{ + if (mAvatarNameCallbackConnection.connected()) + { + mAvatarNameCallbackConnection.disconnect(); + } + + LLScrollListCtrl* search_results = getChild("search_results_people"); + + if (av_name.getAccountName() != "(?\?\?).(?\?\?)") + { + LLSD content; + LLSD data; + data["id"] = id; + + data["columns"][0]["column"] = "icon"; + data["columns"][0]["type"] = "icon"; + data["columns"][0]["value"] = "icon_avatar_offline.tga"; + + data["columns"][1]["name"] = "username"; + data["columns"][1]["value"] = av_name.getUserName(); + + content["name"] = av_name.getUserName(); + + search_results->addElement(data); + + mResultsContent[id.asString()] = content; + mResultsReceived = 1; + mNumResultsReturned = 1; + + search_results->setEnabled(TRUE); + search_results->selectFirstItem(); + search_results->setFocus(TRUE); + onSelectItem(); + } + else + { + LLStringUtil::format_map_t map; + map["[TEXT]"] = getChild("people_edit")->getValue().asString(); + search_results->setEnabled(FALSE); + search_results->setCommentText(LLTrans::getString("not_found", map)); + } +} + //////////////////////////////////////// // Groups Search Panel // //////////////////////////////////////// diff --git a/indra/newview/fsfloatersearch.h b/indra/newview/fsfloatersearch.h index 0f6ba1b52a..eff98d68c8 100644 --- a/indra/newview/fsfloatersearch.h +++ b/indra/newview/fsfloatersearch.h @@ -55,7 +55,7 @@ struct SearchQuery : public LLInitParam::Block { Optional category; Optional query; - + SearchQuery(); }; @@ -77,13 +77,13 @@ class FSPanelSearchPeople : public FSSearchPanelBase public: FSPanelSearchPeople(); static void processSearchReply(LLMessageSystem* msg, void**); - + /*virtual*/ void focusDefaultElement(); protected: const S32& getNumResultsReturned() const { return mNumResultsReturned; }; const S32& getNumResultsReceived() const { return mResultsReceived; }; - + private: /*virtual*/ BOOL postBuild(); virtual ~FSPanelSearchPeople(); @@ -92,20 +92,24 @@ private: void onSelectItem(); void onBtnNext(); void onBtnBack(); - + void find(); void resetSearch(); S32 showNextButton(S32); - void setLoadingProgress(bool started); - + const LLUUID& getQueryID() const { return mQueryID; } - + + void onAvatarNameCallback(const LLUUID& id, const LLAvatarName& av_name); + + typedef boost::signals2::connection avatar_name_callback_connection_t; + avatar_name_callback_connection_t mAvatarNameCallbackConnection; + S32 mNumResultsReturned; S32 mStartSearch; S32 mResultsReceived; LLSD mResultsContent; LLUUID mQueryID; - + FSFloaterSearch* mParent; LLSearchComboBox* mSearchComboBox; FSScrollListCtrl* mSearchResults; @@ -117,25 +121,24 @@ class FSPanelSearchGroups : public FSSearchPanelBase public: FSPanelSearchGroups(); static void processSearchReply(LLMessageSystem* msg, void**); - + /*virtual*/ void focusDefaultElement(); private: /*virtual*/ BOOL postBuild(); virtual ~FSPanelSearchGroups(); - + void onBtnFind(); void onSelectItem(); void onBtnNext(); void onBtnBack(); - + void find(); void resetSearch(); S32 showNextButton(S32); - void setLoadingProgress(bool started); - + const LLUUID& getQueryID() const { return mQueryID; } - + S32 mNumResultsReturned; S32 mStartSearch; S32 mResultsReceived; @@ -153,23 +156,22 @@ class FSPanelSearchPlaces : public FSSearchPanelBase public: FSPanelSearchPlaces(); static void processSearchReply(LLMessageSystem* msg, void**); - + /*virtual*/ void focusDefaultElement(); private: /*virtual*/ BOOL postBuild(); virtual ~FSPanelSearchPlaces(); - + void onBtnFind(); void onSelectItem(); void onBtnNext(); void onBtnBack(); - + void find(); void resetSearch(); S32 showNextButton(S32); - void setLoadingProgress(bool started); - + const LLUUID& getQueryID() const { return mQueryID; } S32 mNumResultsReturned; @@ -190,29 +192,28 @@ class FSPanelSearchLand : public FSSearchPanelBase public: FSPanelSearchLand(); static void processSearchReply(LLMessageSystem* msg, void**); -protected: + private: /*virtual*/ BOOL postBuild(); virtual ~FSPanelSearchLand(); - + void onBtnFind(); void onSelectItem(); void onBtnNext(); void onBtnBack(); - + void find(); void resetSearch(); S32 showNextButton(S32); - void setLoadingProgress(bool started); - + const LLUUID& getQueryID() const { return mQueryID; } - + S32 mNumResultsReturned; S32 mStartSearch; S32 mResultsReceived; LLSD mResultsContent; LLUUID mQueryID; - + FSFloaterSearch* mParent; LLLineEditor* mPriceEditor; LLLineEditor* mAreaEditor; @@ -231,17 +232,16 @@ public: private: /*virtual*/ BOOL postBuild(); virtual ~FSPanelSearchClassifieds(); - + void onBtnFind(); void onSelectItem(); void onBtnNext(); void onBtnBack(); - + void find(); void resetSearch(); S32 showNextButton(S32); - void setLoadingProgress(bool started); - + const LLUUID& getQueryID() const { return mQueryID; } S32 mNumResultsReturned; @@ -262,13 +262,13 @@ class FSPanelSearchEvents : public FSSearchPanelBase public: FSPanelSearchEvents(); static void processSearchReply(LLMessageSystem* msg, void**); - + /*virtual*/ void focusDefaultElement(); private: /*virtual*/ BOOL postBuild(); virtual ~FSPanelSearchEvents(); - + void onBtnFind(); void onSelectItem(); void onBtnNext(); @@ -282,10 +282,9 @@ private: void onSearchModeChanged(); void resetSearch(); S32 showNextButton(S32); - void setLoadingProgress(bool started); - + const LLUUID& getQueryID() const { return mQueryID; } - + S32 mNumResultsReturned; S32 mResultsReceived; S32 mStartSearch; @@ -312,7 +311,7 @@ public: private: virtual ~FSPanelSearchWeb() {}; - + LLMediaCtrl* mWebBrowser; LLSD mCategoryPaths; @@ -330,19 +329,19 @@ public: SC_PLACE, SC_CLASSIFIED } ESearchCategory; - + struct _Params : public LLInitParam::Block<_Params, LLFloater::Params> { Optional search; }; - + typedef LLSDParamAdapter<_Params> Params; FSFloaterSearch(const Params& key); ~FSFloaterSearch(); void onOpen(const LLSD& key); BOOL postBuild(); - + void avatarNameUpdatedCallback(const LLUUID& id, const LLAvatarName& av_name); void groupNameUpdatedCallback(const LLUUID& id, const std::string& name, bool is_group); void onSelectedItem(const LLUUID& selected_item, ESearchCategory type); @@ -365,7 +364,7 @@ public: template static T* getSearchPanel(const std::string& panel_name); - + private: virtual void onClose(bool app_quitting); const LLUUID& getSelectedID() { return mSelectedID; } @@ -373,7 +372,7 @@ private: LLUUID mSelectedID; U32 mEventID; bool mHasSelection; - + void resetVerbs(); void flushDetails(); void onTabChange(); @@ -386,11 +385,11 @@ private: void onBtnEventReminder(); void onBtnTeleport(); void onBtnMap(); - + LLRemoteParcelInfoObserver* mRemoteParcelObserver; LLAvatarPropertiesObserver* mAvatarPropertiesObserver; LLGroupMgrObserver* mGroupPropertiesRequest; - + FSPanelSearchPeople* mPanelPeople; FSPanelSearchGroups* mPanelGroups; FSPanelSearchPlaces* mPanelPlaces; @@ -398,7 +397,7 @@ private: FSPanelSearchLand* mPanelLand; FSPanelSearchClassifieds* mPanelClassifieds; FSPanelSearchWeb* mPanelWeb; - + LLPanel* mDetailsPanel; LLTextEditor* mDetailTitle; LLTextEditor* mDetailDesc; diff --git a/indra/newview/fspanellogin.cpp b/indra/newview/fspanellogin.cpp index c8ddc70d8a..ab9da81de5 100644 --- a/indra/newview/fspanellogin.cpp +++ b/indra/newview/fspanellogin.cpp @@ -487,6 +487,16 @@ void FSPanelLogin::show(const LLRect &rect, gFocusMgr.setDefaultKeyboardFocus(sInstance); } +//static +void FSPanelLogin::reshapePanel() +{ + if (sInstance) + { + LLRect rect = sInstance->getRect(); + sInstance->reshape(rect.getWidth(), rect.getHeight()); + } +} + // static void FSPanelLogin::setFields(LLPointer credential, bool from_startup /* = false*/) { diff --git a/indra/newview/fspanellogin.h b/indra/newview/fspanellogin.h index 9ce2509404..098cf9335f 100644 --- a/indra/newview/fspanellogin.h +++ b/indra/newview/fspanellogin.h @@ -53,6 +53,7 @@ public: static void show(const LLRect &rect, void (*callback)(S32 option, void* user_data), void* callback_data); + static void reshapePanel(); static void setFields(LLPointer credential, bool from_startup = false); diff --git a/indra/newview/fsradarentry.cpp b/indra/newview/fsradarentry.cpp index a8cc359108..2504b1c5c9 100644 --- a/indra/newview/fsradarentry.cpp +++ b/indra/newview/fsradarentry.cpp @@ -35,7 +35,7 @@ FSRadarEntry::FSRadarEntry(const LLUUID& avid) : mID(avid), - mName(avid.asString()), + mName(LLTrans::getString("AvatarNameWaiting")), mUserName(LLStringUtil::null), mDisplayName(LLStringUtil::null), mRange(0.f), diff --git a/indra/newview/installers/windows/install_icon.BMP b/indra/newview/installers/windows/install_icon.BMP index 09df573870..dba2636803 100644 Binary files a/indra/newview/installers/windows/install_icon.BMP and b/indra/newview/installers/windows/install_icon.BMP differ diff --git a/indra/newview/installers/windows/uninstall_icon.BMP b/indra/newview/installers/windows/uninstall_icon.BMP index 562b56676a..dba2636803 100644 Binary files a/indra/newview/installers/windows/uninstall_icon.BMP and b/indra/newview/installers/windows/uninstall_icon.BMP differ diff --git a/indra/newview/llappdelegate-objc.mm b/indra/newview/llappdelegate-objc.mm index 7bd94a0f03..cfad3a5d1f 100644 --- a/indra/newview/llappdelegate-objc.mm +++ b/indra/newview/llappdelegate-objc.mm @@ -134,6 +134,7 @@ // called again. Since it returned false, do not yet cancel // frameTimer. handleQuit(); + [[NSApplication sharedApplication] stopModal]; return NSTerminateCancel; } else { // pumpMainLoop() returned true: it's done. Okay, done with frameTimer. diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 5611f6adfb..e7dafbb7b8 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -2602,6 +2602,52 @@ void LLAppearanceMgr::enforceCOFItemRestrictions(LLPointer } } +bool sort_by_linked_uuid(const LLViewerInventoryItem* item1, const LLViewerInventoryItem* item2) +{ + if (!item1 || !item2) + { + LL_WARNS() << "item1, item2 cannot be null, something is very wrong" << LL_ENDL; + return true; + } + + return item1->getLinkedUUID() < item2->getLinkedUUID(); +} + +void get_sorted_base_and_cof_items(LLInventoryModel::item_array_t& cof_item_array, LLInventoryModel::item_array_t& outfit_item_array) +{ + LLUUID base_outfit_id = LLAppearanceMgr::instance().getBaseOutfitUUID(); + + if (base_outfit_id.notNull()) + { + LLIsValidItemLink collector; + LLInventoryModel::cat_array_t sub_cat_array; + + gInventory.collectDescendents(base_outfit_id, + sub_cat_array, + outfit_item_array, + LLInventoryModel::EXCLUDE_TRASH); + + LLInventoryModel::cat_array_t cof_cats; + + gInventory.collectDescendentsIf(LLAppearanceMgr::instance().getCOF(), cof_cats, cof_item_array, + LLInventoryModel::EXCLUDE_TRASH, collector); + + for (U32 i = 0; i < outfit_item_array.size(); ++i) + { + LLViewerInventoryItem* linked_item = outfit_item_array.at(i)->getLinkedItem(); + if (linked_item != NULL && linked_item->getActualType() == LLAssetType::AT_TEXTURE) + { + outfit_item_array.erase(outfit_item_array.begin() + i); + break; + } + } + + std::sort(cof_item_array.begin(), cof_item_array.end(), sort_by_linked_uuid); + std::sort(outfit_item_array.begin(), outfit_item_array.end(), sort_by_linked_uuid); + } +} + + void LLAppearanceMgr::updateAppearanceFromCOF(bool enforce_item_restrictions, bool enforce_ordering, nullary_func_t post_update_func) @@ -2647,7 +2693,43 @@ void LLAppearanceMgr::updateAppearanceFromCOF(bool enforce_item_restrictions, if (!validateClothingOrderingInfo()) { - LL_WARNS() << "Clothing ordering error" << LL_ENDL; + + LLInventoryModel::item_array_t outfit_item_array; + LLInventoryModel::item_array_t cof_item_array; + get_sorted_base_and_cof_items(cof_item_array, outfit_item_array); + + // Exclude LSL bridge or the following size check will always fail! + for (LLInventoryModel::item_array_t::iterator i = cof_item_array.begin(); i != cof_item_array.end(); ++i) + { + LLViewerInventoryItem *item = *i; + + if (FSLSLBridge::instance().isBridgeValid() && item && item->getLinkedUUID() == FSLSLBridge::instance().getBridge()->getUUID()) + { + cof_item_array.erase(i); + break; + } + } + // + + if (outfit_item_array.size() == cof_item_array.size()) + { + for (U32 i = 0; i < cof_item_array.size(); ++i) + { + LLViewerInventoryItem *cof_it = cof_item_array.at(i); + LLViewerInventoryItem *base_it = outfit_item_array.at(i); + + if (cof_it->getActualDescription() != base_it->getActualDescription()) + { + if (cof_it->getLinkedUUID() == base_it->getLinkedUUID()) + { + cof_it->setDescription(base_it->getActualDescription()); + gInventory.updateItem(cof_it); + } + } + } + LLAppearanceMgr::getInstance()->updateIsDirty(); + } + } BoolSetter setIsInUpdateAppearanceFromCOF(mIsInUpdateAppearanceFromCOF); @@ -3395,17 +3477,6 @@ void LLAppearanceMgr::removeCOFLinksOfType(LLWearableType::EType type, LLPointer } } -bool sort_by_linked_uuid(const LLViewerInventoryItem* item1, const LLViewerInventoryItem* item2) -{ - if (!item1 || !item2) - { - LL_WARNS() << "item1, item2 cannot be null, something is very wrong" << LL_ENDL; - return true; - } - - return item1->getLinkedUUID() < item2->getLinkedUUID(); -} - void LLAppearanceMgr::updateIsDirty() { LLUUID cof = getCOF(); diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 7817bf9210..03a2e4f1e0 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -1365,7 +1365,16 @@ bool LLAppViewer::init() // // add LEAP mode command-line argument to whichever of these we selected // updater.args.add("leap"); // // UpdaterServiceSettings -// updater.args.add(stringize(gSavedSettings.getU32("UpdaterServiceSetting"))); +// if (gSavedSettings.getBOOL("FirstLoginThisInstall")) +// { +// // Befor first login, treat this as 'manual' updates, +// // updater won't install anything, but required updates +// updater.args.add("0"); +// } +// else +// { +// updater.args.add(stringize(gSavedSettings.getU32("UpdaterServiceSetting"))); +// } // // channel // updater.args.add(LLVersionInfo::instance().getChannel()); // // testok @@ -1951,6 +1960,7 @@ bool LLAppViewer::doFrame() } delete gServicePump; + gServicePump = NULL; destroyMainloopTimeout(); @@ -2011,7 +2021,11 @@ bool LLAppViewer::cleanup() //dump scene loading monitor results if (LLSceneMonitor::instanceExists()) { - LLSceneMonitor::instance().dumpToFile(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "scene_monitor_results.csv")); + if (!isSecondInstance()) + { + LLSceneMonitor::instance().dumpToFile(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "scene_monitor_results.csv")); + } + LLSceneMonitor::deleteSingleton(); } // There used to be an 'if (LLFastTimerView::sAnalyzePerformance)' block @@ -4261,6 +4275,12 @@ void LLAppViewer::writeSystemInfo() gDebugInfo["FirstRunThisInstall"] = gSavedSettings.getBOOL("FirstRunThisInstall"); gDebugInfo["StartupState"] = LLStartUp::getStartupStateString(); + std::vector resolutions = gViewerWindow->getWindow()->getDisplaysResolutionList(); + for (auto res_iter : resolutions) + { + gDebugInfo["DisplayInfo"].append(res_iter); + } + writeDebugInfo(); // Save out debug_info.log early, in case of crash. } @@ -4943,7 +4963,7 @@ bool LLAppViewer::initCache() const double disk_cache_percent = gSavedSettings.getF32("DiskCachePercentOfTotal"); const unsigned int disk_cache_mb = cache_total_size_mb * disk_cache_percent / 100; const unsigned int disk_cache_bytes = disk_cache_mb * 1024 * 1024; - const bool enable_cache_debug_info = gSavedSettings.getBOOL("EnableDiskCacheDebugInfo"); + const bool enable_cache_debug_info = gSavedSettings.getBOOL("EnableCacheDebugInfo"); // Don't ignore cache path for asset cache; Moved further down until cache path has been set correctly //const std::string cache_dir = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, cache_dir_name); //LLDiskCache::initParamSingleton(cache_dir, disk_cache_bytes, enable_cache_debug_info); @@ -4994,10 +5014,10 @@ bool LLAppViewer::initCache() std::string new_cache_location = gSavedSettings.getString("NewCacheLocation"); if (new_cache_location != cache_location) { - // AO: Don't automatically purge old cache location, has unwanted side effects with shared caches, upgrades - //LL_INFOS("AppCache") << "Cache location changed, cache needs purging" << LL_ENDL; - //gDirUtilp->setCacheDir(gSavedSettings.getString("CacheLocation")); - //purgeCache(); // purge old cache + LL_INFOS("AppCache") << "Cache location changed, cache needs purging" << LL_ENDL; + gDirUtilp->setCacheDir(gSavedSettings.getString("CacheLocation")); + purgeCache(); // purge old cache + gDirUtilp->deleteDirAndContents(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, cache_dir_name)); gSavedSettings.setString("CacheLocation", new_cache_location); gSavedSettings.setString("CacheLocationTopFolder", gDirUtilp->getBaseFileName(new_cache_location)); } diff --git a/indra/newview/llattachmentsmgr.cpp b/indra/newview/llattachmentsmgr.cpp index e19c870fbf..22f815dccb 100644 --- a/indra/newview/llattachmentsmgr.cpp +++ b/indra/newview/llattachmentsmgr.cpp @@ -313,7 +313,7 @@ void LLAttachmentsMgr::linkRecentlyArrivedAttachments() { if (isAgentAvatarValid() && gAgentAvatarp->isWearingAttachment(*it) && - !gAgentAvatarp->getWornAttachment(*it)->isTempAttachment() && // Don't link temp attachments in COF! + !gAgentAvatarp->getWornAttachment(*it)->isTempAttachment() && // Don't link temp attachments in COF! !LLAppearanceMgr::instance().isLinkedInCOF(*it)) { LLUUID item_id = *it; diff --git a/indra/newview/llconversationlog.cpp b/indra/newview/llconversationlog.cpp index c91790f9c0..c953efed72 100644 --- a/indra/newview/llconversationlog.cpp +++ b/indra/newview/llconversationlog.cpp @@ -408,6 +408,24 @@ void LLConversationLog::deleteBackupLogs() } } +void LLConversationLog::verifyFilename(const LLUUID& session_id, const std::string &expected_filename, const std::string &new_session_name) +{ + conversations_vec_t::iterator conv_it = mConversations.begin(); + for (; conv_it != mConversations.end(); ++conv_it) + { + if (conv_it->getSessionID() == session_id) + { + if (conv_it->getHistoryFileName() != expected_filename) + { + LLLogChat::renameLogFile(conv_it->getHistoryFileName(), expected_filename); + conv_it->updateHistoryFileName(expected_filename); + conv_it->setConversationName(new_session_name); + } + break; + } + } +} + bool LLConversationLog::moveLog(const std::string &originDirectory, const std::string &targetDirectory) { @@ -543,11 +561,10 @@ bool LLConversationLog::loadFromFile(const std::string& filename) return false; } bool purge_required = false; - // FIRE-30705 protect against silly display names that cause lines to exceed max string length - // char buffer[MAX_STRING]; - static constexpr int BUFFER_1K { 1024 }; // long enough to handle the most extreme Unicode nonsense and some to spare - char buffer[BUFFER_1K]; - // + + static constexpr int UTF_BUFFER{ 1024 }; // long enough to handle the most extreme Unicode nonsense and some to spare + + char buffer[UTF_BUFFER]; char conv_name_buffer[MAX_STRING]; char part_id_buffer[MAX_STRING]; char conv_id_buffer[MAX_STRING]; @@ -558,21 +575,15 @@ bool LLConversationLog::loadFromFile(const std::string& filename) // before CHUI-348 it was a flag of conversation voice state int prereserved_unused; - // FIRE-30705 protect against silly display names that cause lines to exceed max string length - // while (!feof(fp) && fgets(buffer, MAX_STRING, fp)) - // { - // conv_name_buffer[0] = '\0'; - // part_id_buffer[0] = '\0'; - // conv_id_buffer[0] = '\0'; - memset( buffer, '\0', BUFFER_1K ); - while (!feof(fp) && fgets(buffer, BUFFER_1K, fp)) + memset(buffer, '\0', UTF_BUFFER); + while (!feof(fp) && fgets(buffer, UTF_BUFFER, fp)) { - // force blank for added safety - memset( conv_name_buffer, '\0', MAX_STRING ); - memset( part_id_buffer, '\0', MAX_STRING ); - memset( conv_id_buffer, '\0', MAX_STRING ); - memset( history_file_name, '\0', MAX_STRING ); - // + // force blank for added safety + memset(conv_name_buffer, '\0', MAX_STRING); + memset(part_id_buffer, '\0', MAX_STRING); + memset(conv_id_buffer, '\0', MAX_STRING); + memset(history_file_name, '\0', MAX_STRING); + sscanf(buffer, "[%lld] %d %d %d %[^|]| %s %s %[^|]|", &time, &stype, @@ -610,7 +621,7 @@ bool LLConversationLog::loadFromFile(const std::string& filename) } mConversations.push_back(conversation); - memset( buffer, '\0', BUFFER_1K ); // FIRE-30705 clear buffer down + memset(buffer, '\0', UTF_BUFFER); } fclose(fp); diff --git a/indra/newview/llconversationlog.h b/indra/newview/llconversationlog.h index 46e46a3278..820a5db491 100644 --- a/indra/newview/llconversationlog.h +++ b/indra/newview/llconversationlog.h @@ -59,7 +59,7 @@ public: getTime() const { return mTime; } bool hasOfflineMessages() const { return mHasOfflineIMs; } - void setConversationName(std::string conv_name) { mConversationName = conv_name; } + void setConversationName(const std::string &conv_name) { mConversationName = conv_name; } void setOfflineMessages(bool new_messages) { mHasOfflineIMs = new_messages; } bool isOlderThan(U32Days days) const; @@ -68,6 +68,8 @@ public: */ void updateTimestamp(); + void updateHistoryFileName(const std::string &new_name) { mHistoryFileName = new_name; } + /* * Resets flag of unread offline message to false when im floater with this conversation is opened. */ @@ -137,6 +139,8 @@ public: * public method which is called on viewer exit to save conversation log */ void cache(); + // will check if current name is edentical with the one on disk and will rename the one on disk if it isn't + void verifyFilename(const LLUUID& session_id, const std::string &expected_filename, const std::string &new_session_name); bool moveLog(const std::string &originDirectory, const std::string &targetDirectory); void getListOfBackupLogs(std::vector& list_of_backup_logs); void deleteBackupLogs(); diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp index d176c9647c..a6dfe33fcf 100644 --- a/indra/newview/llconversationmodel.cpp +++ b/indra/newview/llconversationmodel.cpp @@ -343,11 +343,36 @@ void LLConversationItemSession::removeParticipant(const LLUUID& participant_id) void LLConversationItemSession::clearParticipants() { + // clearParticipants function potentially is malfunctioning since it only cleans children of models, + // it does nothing to views that own those models (listeners) + // probably needs to post some kind of 'remove all participants' event clearChildren(); mIsLoaded = false; mNeedsRefresh = true; } + +void LLConversationItemSession::clearAndDeparentModels() +{ + std::for_each(mChildren.begin(), mChildren.end(), + [](LLFolderViewModelItem* c) + { + if (c->getNumRefs() == 0) + { + // LLConversationItemParticipant can be created but not assigned to any view, + // it was waiting for an "add_participant" event to be processed + delete c; + } + else + { + // Model is still assigned to some view/widget + c->setParent(NULL); + } + } + ); + mChildren.clear(); +} + LLConversationItemParticipant* LLConversationItemSession::findParticipant(const LLUUID& participant_id) { // This is *not* a general tree parsing algorithm. It assumes that a session contains only diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h index 68bc6d65f4..800d13df3e 100644 --- a/indra/newview/llconversationmodel.h +++ b/indra/newview/llconversationmodel.h @@ -168,6 +168,7 @@ public: void removeParticipant(LLConversationItemParticipant* participant); void removeParticipant(const LLUUID& participant_id); void clearParticipants(); + void clearAndDeparentModels(); // will delete unowned models and deparent owned ones LLConversationItemParticipant* findParticipant(const LLUUID& participant_id); void setParticipantIsMuted(const LLUUID& participant_id, bool is_muted); diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp index 0cf9ea6dfd..456fb699c7 100644 --- a/indra/newview/llconversationview.cpp +++ b/indra/newview/llconversationview.cpp @@ -33,6 +33,7 @@ #include #include "llagentdata.h" +#include "llavataractions.h" #include "llconversationmodel.h" #include "llfloaterimsession.h" #include "llfloaterimnearbychat.h" @@ -104,6 +105,56 @@ LLConversationViewSession::~LLConversationViewSession() mFlashTimer->unset(); } +void LLConversationViewSession::destroyView() +{ + // Chat can create and parent models(listeners) to session's model before creating + // coresponding views, such participant's models normally will wait for idle cycles + // but since we are deleting session and won't be processing any more events, make + // sure unowned LLConversationItemParticipant models are removed as well. + + LLConversationItemSession* vmi = dynamic_cast(getViewModelItem()); + + // CONV_SESSION_1_ON_1 stores participants as two models that belong to views independent + // from session (nasty! These views are widgets in LLFloaterIMSessionTab, see buildConversationViewParticipant) + if (vmi && vmi->getType() != LLConversationItem::CONV_SESSION_1_ON_1) + { + // Destroy existing views + while (!mItems.empty()) + { + LLFolderViewItem *itemp = mItems.back(); + mItems.pop_back(); + + LLFolderViewModelItem* item_vmi = itemp->getViewModelItem(); + if (item_vmi) // supposed to exist + { + // unparent to remove from child list + vmi->removeChild(item_vmi); + } + itemp->destroyView(); + } + + // Not needed in scope of sessions, but just in case + while (!mFolders.empty()) + { + LLFolderViewFolder *folderp = mFolders.back(); + mFolders.pop_back(); + + LLFolderViewModelItem* folder_vmi = folderp->getViewModelItem(); + if (folder_vmi) + { + vmi->removeChild(folder_vmi); + } + folderp->destroyView(); + } + + // Now everything that is left in model(listener) is not owned by views, + // only by sessions, deparent so it won't point to soon to be dead model + vmi->clearAndDeparentModels(); + } + + LLFolderViewFolder::destroyView(); +} + void LLConversationViewSession::setFlashState(bool flash_state) { if (flash_state && !mFlashStateOn) @@ -434,8 +485,13 @@ void LLConversationViewSession::refresh() vmi->resetRefresh(); if (mSessionTitle) - { - mSessionTitle->setText(vmi->getDisplayName()); + { + if (!highlightFriendTitle(vmi)) + { + LLStyle::Params title_style; + title_style.color = LLUIColorTable::instance().getColor("LabelTextColor"); + mSessionTitle->setText(vmi->getDisplayName(), title_style); + } } // Update all speaking indicators @@ -480,6 +536,22 @@ void LLConversationViewSession::onCurrentVoiceSessionChanged(const LLUUID& sessi } } +bool LLConversationViewSession::highlightFriendTitle(LLConversationItem* vmi) +{ + if(vmi->getType() == LLConversationItem::CONV_PARTICIPANT || vmi->getType() == LLConversationItem::CONV_SESSION_1_ON_1) + { + LLIMModel::LLIMSession* session= LLIMModel::instance().findIMSession(vmi->getUUID()); + if (session && LLAvatarActions::isFriend(session->mOtherParticipantID)) + { + LLStyle::Params title_style; + title_style.color = LLUIColorTable::instance().getColor("ConversationFriendColor"); + mSessionTitle->setText(vmi->getDisplayName(), title_style); + return true; + } + } + return false; +} + // // Implementation of conversations list participant (avatar) widgets // @@ -580,7 +652,14 @@ void LLConversationViewParticipant::draw() } else { - color = mIsSelected ? sHighlightFgColor : sFgColor; + if (LLAvatarActions::isFriend(mUUID)) + { + color = LLUIColorTable::instance().getColor("ConversationFriendColor"); + } + else + { + color = mIsSelected ? sHighlightFgColor : sFgColor; + } } LLConversationItemParticipant* participant_model = dynamic_cast(getViewModelItem()); diff --git a/indra/newview/llconversationview.h b/indra/newview/llconversationview.h index 70e0a2d8e0..d6072101f7 100644 --- a/indra/newview/llconversationview.h +++ b/indra/newview/llconversationview.h @@ -38,6 +38,7 @@ class LLTextBox; class LLFloater; class LLFloaterIMContainer; +class LLConversationItem; class LLConversationViewSession; class LLConversationViewParticipant; @@ -68,6 +69,8 @@ protected: public: virtual ~LLConversationViewSession(); + /*virtual*/ void destroyView(); + /*virtual*/ BOOL postBuild(); /*virtual*/ void draw(); /*virtual*/ BOOL handleMouseDown( S32 x, S32 y, MASK mask ); @@ -95,6 +98,8 @@ public: LLFloater* getSessionFloater(); bool isInActiveVoiceChannel() { return mIsInActiveVoiceChannel; } + bool highlightFriendTitle(LLConversationItem* vmi); + private: void onCurrentVoiceSessionChanged(const LLUUID& session_id); diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 64fae234b8..9e3e45e4ab 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -2317,7 +2317,7 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow) if (mat) { - switch (LLMaterial::eDiffuseAlphaMode(mat->getDiffuseAlphaMode())) + switch (LLMaterial::eDiffuseAlphaMode(mat->getDiffuseAlphaModeRender())) { case LLMaterial::DIFFUSE_ALPHA_MODE_MASK: { @@ -2460,7 +2460,7 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow) sVertexProgram->uniform4f(LLShaderMgr::SPECULAR_COLOR, col.mV[0], col.mV[1], col.mV[2], spec); sVertexProgram->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, env); - if (mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK) + if (mat->getDiffuseAlphaModeRender() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK) { F32 cutoff = mat->getAlphaMaskCutoff()/255.f; sVertexProgram->setMinimumAlpha(cutoff); diff --git a/indra/newview/llenvironment.cpp b/indra/newview/llenvironment.cpp index 95ec93d823..a9afd3b72d 100644 --- a/indra/newview/llenvironment.cpp +++ b/indra/newview/llenvironment.cpp @@ -2074,6 +2074,10 @@ void LLEnvironment::coroRequestEnvironment(S32 parcel_id, LLEnvironment::environ { LL_WARNS("ENVIRONMENT") << "Couldn't retrieve environment settings for " << ((parcel_id == INVALID_PARCEL_ID) ? ("region!") : ("parcel!")) << LL_ENDL; } + else if (LLApp::isExiting()) + { + return; + } else { LLSD environment = result[KEY_ENVIRONMENT]; @@ -2163,6 +2167,10 @@ void LLEnvironment::coroUpdateEnvironment(S32 parcel_id, S32 track_no, UpdateInf notify = LLSD::emptyMap(); notify["FAIL_REASON"] = result["message"].asString(); } + else if (LLApp::isExiting()) + { + return; + } else { LLSD environment = result[KEY_ENVIRONMENT]; @@ -2225,6 +2233,10 @@ void LLEnvironment::coroResetEnvironment(S32 parcel_id, S32 track_no, environmen notify = LLSD::emptyMap(); notify["FAIL_REASON"] = result["message"].asString(); } + else if (LLApp::isExiting()) + { + return; + } else { LLSD environment = result[KEY_ENVIRONMENT]; diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 6576ab783a..333c417c7f 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -1144,6 +1144,13 @@ bool LLFace::calcAlignedPlanarTE(const LLFace* align_to, LLVector2* res_st_offs F32 map_rot = 0.f, map_scaleS = 0.f, map_scaleT = 0.f, map_offsS = 0.f, map_offsT = 0.f; + LLMaterial* mat = orig_tep->getMaterialParams(); + if (!mat && map != LLRender::DIFFUSE_MAP) + { + LL_WARNS_ONCE("llface") << "Face is set to use specular or normal map but has no material, defaulting to diffuse" << LL_ENDL; + map = LLRender::DIFFUSE_MAP; + } + switch (map) { case LLRender::DIFFUSE_MAP: @@ -1154,26 +1161,26 @@ bool LLFace::calcAlignedPlanarTE(const LLFace* align_to, LLVector2* res_st_offs map_offsT = orig_tep->mOffsetT; break; case LLRender::NORMAL_MAP: - if (orig_tep->getMaterialParams()->getNormalID().isNull()) + if (mat->getNormalID().isNull()) { return false; } - map_rot = orig_tep->getMaterialParams()->getNormalRotation(); - map_scaleS = orig_tep->getMaterialParams()->getNormalRepeatX(); - map_scaleT = orig_tep->getMaterialParams()->getNormalRepeatY(); - map_offsS = orig_tep->getMaterialParams()->getNormalOffsetX(); - map_offsT = orig_tep->getMaterialParams()->getNormalOffsetY(); + map_rot = mat->getNormalRotation(); + map_scaleS = mat->getNormalRepeatX(); + map_scaleT = mat->getNormalRepeatY(); + map_offsS = mat->getNormalOffsetX(); + map_offsT = mat->getNormalOffsetY(); break; case LLRender::SPECULAR_MAP: - if (orig_tep->getMaterialParams()->getSpecularID().isNull()) + if (mat->getSpecularID().isNull()) { return false; } - map_rot = orig_tep->getMaterialParams()->getSpecularRotation(); - map_scaleS = orig_tep->getMaterialParams()->getSpecularRepeatX(); - map_scaleT = orig_tep->getMaterialParams()->getSpecularRepeatY(); - map_offsS = orig_tep->getMaterialParams()->getSpecularOffsetX(); - map_offsT = orig_tep->getMaterialParams()->getSpecularOffsetY(); + map_rot = mat->getSpecularRotation(); + map_scaleS = mat->getSpecularRepeatX(); + map_scaleT = mat->getSpecularRepeatY(); + map_offsS = mat->getSpecularOffsetX(); + map_offsT = mat->getSpecularOffsetY(); break; default: /*make compiler happy*/ break; @@ -1235,7 +1242,7 @@ bool LLFace::canRenderAsMask() } LLMaterial* mat = te->getMaterialParams(); - if (mat && mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND) + if (mat && mat->getDiffuseAlphaModeRender() == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND) { return false; } @@ -1508,7 +1515,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, } else { - if (!mat || mat->getDiffuseAlphaMode() != LLMaterial::DIFFUSE_ALPHA_MODE_MASK) + if (!mat || mat->getDiffuseAlphaModeRender() != LLMaterial::DIFFUSE_ALPHA_MODE_MASK) { shiny_in_alpha = true; } diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp index 08c808ebe3..f69f75e6d3 100644 --- a/indra/newview/llfavoritesbar.cpp +++ b/indra/newview/llfavoritesbar.cpp @@ -513,6 +513,8 @@ LLFavoritesBarCtrl::LLFavoritesBarCtrl(const LLFavoritesBarCtrl::Params& p) mUpdateDropDownItems(true), mRestoreOverflowMenu(false), mGetPrevItems(true), + mMouseX(0), + mMouseY(0), mItemsChangedTimer() { // Register callback for menus with current registrar (will be parent panel's registrar) @@ -529,12 +531,12 @@ LLFavoritesBarCtrl::LLFavoritesBarCtrl(const LLFavoritesBarCtrl::Params& p) // Allow V3 and FS style favorites bar //LLTextBox::Params more_button_params(p.more_button); //mMoreTextBox = LLUICtrlFactory::create (more_button_params); - //mMoreTextBox->setClickedCallback(boost::bind(&LLFavoritesBarCtrl::showDropDownMenu, this)); + //mMoreTextBox->setClickedCallback(boost::bind(&LLFavoritesBarCtrl::onMoreTextBoxClicked, this)); //addChild(mMoreTextBox); if (p.chevron_button.isProvided()) { - LLButton::Params chevron_button_params(p.chevron_button); - chevron_button_params.click_callback.function(boost::bind(&LLFavoritesBarCtrl::showDropDownMenu, this)); + LLButton::Params chevron_button_params(p.chevron_button); + chevron_button_params.click_callback.function(boost::bind(&LLFavoritesBarCtrl::onMoreTextBoxClicked, this)); mMoreCtrl = LLUICtrlFactory::create (chevron_button_params); addChild(mMoreCtrl); } @@ -542,7 +544,7 @@ LLFavoritesBarCtrl::LLFavoritesBarCtrl(const LLFavoritesBarCtrl::Params& p) { LLTextBox::Params more_button_params(p.more_button); mMoreCtrl = LLUICtrlFactory::create (more_button_params); - ((LLTextBox*)mMoreCtrl)->setClickedCallback(boost::bind(&LLFavoritesBarCtrl::showDropDownMenu, this)); + ((LLTextBox*)mMoreCtrl)->setClickedCallback(boost::bind(&LLFavoritesBarCtrl::onMoreTextBoxClicked, this)); addChild(mMoreCtrl); } // @@ -1141,6 +1143,12 @@ BOOL LLFavoritesBarCtrl::collectFavoriteItems(LLInventoryModel::item_array_t &it return TRUE; } +void LLFavoritesBarCtrl::onMoreTextBoxClicked() +{ + LLUI::getInstance()->getMousePositionScreen(&mMouseX, &mMouseY); + showDropDownMenu(); +} + void LLFavoritesBarCtrl::showDropDownMenu() { if (mOverflowMenuHandle.isDead()) @@ -1299,7 +1307,7 @@ void LLFavoritesBarCtrl::positionAndShowMenu(LLToggleableMenu* menu) } } - LLMenuGL::showPopup(this, menu, menu_x, menu_y); + LLMenuGL::showPopup(this, menu, menu_x, menu_y, mMouseX, mMouseY); } void LLFavoritesBarCtrl::onButtonClick(LLUUID item_id) diff --git a/indra/newview/llfavoritesbar.h b/indra/newview/llfavoritesbar.h index 907eab9e9f..50bca11ecc 100644 --- a/indra/newview/llfavoritesbar.h +++ b/indra/newview/llfavoritesbar.h @@ -99,6 +99,8 @@ protected: void showDropDownMenu(); + void onMoreTextBoxClicked(); + LLHandle mOverflowMenuHandle; LLHandle mContextMenuHandle; @@ -170,6 +172,9 @@ private: BOOL mTabsHighlightEnabled; + S32 mMouseX; + S32 mMouseY; + boost::signals2::connection mEndDragConnection; }; diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp index a2e28d6975..cdc91b30e7 100644 --- a/indra/newview/llfeaturemanager.cpp +++ b/indra/newview/llfeaturemanager.cpp @@ -384,22 +384,6 @@ F32 gpu_benchmark(); #if LL_WINDOWS -static const U32 STATUS_MSC_EXCEPTION = 0xE06D7363; // compiler specific - -U32 exception_benchmark_filter(U32 code, struct _EXCEPTION_POINTERS *exception_infop) -{ - if (code == STATUS_MSC_EXCEPTION) - { - // C++ exception, go on - return EXCEPTION_CONTINUE_SEARCH; - } - else - { - // handle it - return EXCEPTION_EXECUTE_HANDLER; - } -} - F32 logExceptionBenchmark() { // Todo: make a wrapper/class for SEH exceptions @@ -408,7 +392,7 @@ F32 logExceptionBenchmark() { gbps = gpu_benchmark(); } - __except (exception_benchmark_filter(GetExceptionCode(), GetExceptionInformation())) + __except (msc_exception_filter(GetExceptionCode(), GetExceptionInformation())) { // convert to C++ styled exception char integer_string[32]; diff --git a/indra/newview/llfloateravatarpicker.cpp b/indra/newview/llfloateravatarpicker.cpp index 1aa794cab9..a7eef44fc1 100644 --- a/indra/newview/llfloateravatarpicker.cpp +++ b/indra/newview/llfloateravatarpicker.cpp @@ -243,7 +243,7 @@ void LLFloaterAvatarPicker::onBtnFindUUID() { LLScrollListCtrl* search_results = getChild("SearchResultsUUID"); search_results->deleteAllItems(); - search_results->setCommentText("searching"); + search_results->setCommentText(getString("searching")); if (mFindUUIDAvatarNameCacheConnection.connected()) { diff --git a/indra/newview/llfloaterbuy.cpp b/indra/newview/llfloaterbuy.cpp index e530eb4bbf..a90c98405f 100644 --- a/indra/newview/llfloaterbuy.cpp +++ b/indra/newview/llfloaterbuy.cpp @@ -49,7 +49,8 @@ #include "lltrans.h" LLFloaterBuy::LLFloaterBuy(const LLSD& key) -: LLFloater(key) +: LLFloater(key), + mSelectionUpdateSlot() { } @@ -182,12 +183,19 @@ void LLFloaterBuy::show(const LLSaleInfo& sale_info) floater->getChild("buy_text")->setTextArg("[AMOUNT]", llformat("%d", sale_info.getSalePrice())); floater->getChild("buy_name_text")->setTextArg("[NAME]", owner_name); + floater->showViews(true); + // Must do this after the floater is created, because // sometimes the inventory is already there and // the callback is called immediately. LLViewerObject* obj = selection->getFirstRootObject(); floater->registerVOInventoryListener(obj,NULL); floater->requestVOInventory(); + + if (!floater->mSelectionUpdateSlot.connected()) + { + floater->mSelectionUpdateSlot = LLSelectMgr::getInstance()->mUpdateSignal.connect(boost::bind(&LLFloaterBuy::onSelectionChanged, floater)); + } } void LLFloaterBuy::inventoryChanged(LLViewerObject* obj, @@ -283,6 +291,33 @@ void LLFloaterBuy::inventoryChanged(LLViewerObject* obj, removeVOInventoryListener(); } +void LLFloaterBuy::onSelectionChanged() +{ + + if (LLSelectMgr::getInstance()->getEditSelection()->getRootObjectCount() == 0) + { + removeVOInventoryListener(); + closeFloater(); + } + else if (LLSelectMgr::getInstance()->getEditSelection()->getRootObjectCount() > 1) + { + removeVOInventoryListener(); + showViews(false); + reset(); + // + // setTitle(getString("mupliple_selected")); + setTitle(getString("multiple_selected")); + // + } +} + +void LLFloaterBuy::showViews(bool show) +{ + getChild("buy_btn")->setEnabled(show); + getChild("buy_text")->setVisible(show); + getChild("buy_name_text")->setVisible(show); +} + void LLFloaterBuy::onClickBuy() { // Put the items where we put new folders. @@ -306,5 +341,10 @@ void LLFloaterBuy::onClickCancel() // virtual void LLFloaterBuy::onClose(bool app_quitting) { + if (mSelectionUpdateSlot.connected()) + { + mSelectionUpdateSlot.disconnect(); + } + mObjectSelection.clear(); } diff --git a/indra/newview/llfloaterbuy.h b/indra/newview/llfloaterbuy.h index 3ec642dee1..e83b3c6ba6 100644 --- a/indra/newview/llfloaterbuy.h +++ b/indra/newview/llfloaterbuy.h @@ -63,12 +63,17 @@ protected: S32 serial_num, void* data); + void onSelectionChanged(); + void showViews(bool show); + void onClickBuy(); void onClickCancel(); private: LLSafeHandle mObjectSelection; LLSaleInfo mSaleInfo; + + boost::signals2::connection mSelectionUpdateSlot; }; #endif diff --git a/indra/newview/llfloatercamera.cpp b/indra/newview/llfloatercamera.cpp index 757fefbf86..fc95aec90b 100644 --- a/indra/newview/llfloatercamera.cpp +++ b/indra/newview/llfloatercamera.cpp @@ -565,6 +565,7 @@ void LLFloaterCamera::switchMode(ECameraControlMode mode) switch (mode) { + case CAMERA_CTRL_MODE_PRESETS: case CAMERA_CTRL_MODE_PAN: sFreeCamera = false; clear_camera_tool(); @@ -575,13 +576,6 @@ void LLFloaterCamera::switchMode(ECameraControlMode mode) activate_camera_tool(); break; - case CAMERA_CTRL_MODE_PRESETS: - if(sFreeCamera) - { - switchMode(CAMERA_CTRL_MODE_FREE_CAMERA); - } - break; - default: //normally we won't occur here llassert_always(FALSE); @@ -639,7 +633,6 @@ void LLFloaterCamera::onClickCameraItem(const LLSD& param) camera_floater->mCurrMode == CAMERA_CTRL_MODE_FREE_CAMERA ? camera_floater->switchMode(CAMERA_CTRL_MODE_PAN) : camera_floater->switchMode(CAMERA_CTRL_MODE_FREE_CAMERA); // camera_floater->updateItemsSelection(); - camera_floater->fromFreeToPresets(); } // Phototools camera @@ -651,7 +644,6 @@ void LLFloaterCamera::onClickCameraItem(const LLSD& param) camera_floater->mCurrMode == CAMERA_CTRL_MODE_FREE_CAMERA ? camera_floater->switchMode(CAMERA_CTRL_MODE_PAN) : camera_floater->switchMode(CAMERA_CTRL_MODE_FREE_CAMERA); // camera_floater->updateItemsSelection(); - camera_floater->fromFreeToPresets(); } // @@ -664,7 +656,6 @@ void LLFloaterCamera::onClickCameraItem(const LLSD& param) camera_floater->mCurrMode == CAMERA_CTRL_MODE_FREE_CAMERA ? camera_floater->switchMode(CAMERA_CTRL_MODE_PAN) : camera_floater->switchMode(CAMERA_CTRL_MODE_FREE_CAMERA); // camera_floater->updateItemsSelection(); - camera_floater->fromFreeToPresets(); } // } @@ -766,7 +757,7 @@ void LLFloaterCamera::switchToPreset(const std::string& name) if (camera_floater) { camera_floater->updateItemsSelection(); - camera_floater->fromFreeToPresets(); + camera_floater->switchMode(CAMERA_CTRL_MODE_PRESETS); } // Phototools camera @@ -774,7 +765,7 @@ void LLFloaterCamera::switchToPreset(const std::string& name) if (camera_floater) { camera_floater->updateItemsSelection(); - camera_floater->fromFreeToPresets(); + camera_floater->switchMode(CAMERA_CTRL_MODE_PRESETS); } // @@ -783,19 +774,11 @@ void LLFloaterCamera::switchToPreset(const std::string& name) if (camera_floater) { camera_floater->updateItemsSelection(); - camera_floater->fromFreeToPresets(); + camera_floater->switchMode(CAMERA_CTRL_MODE_PRESETS); } // } -void LLFloaterCamera::fromFreeToPresets() -{ - if (!sFreeCamera && mCurrMode == CAMERA_CTRL_MODE_FREE_CAMERA && mPrevMode == CAMERA_CTRL_MODE_PRESETS) - { - switchMode(CAMERA_CTRL_MODE_PRESETS); - } -} - void LLFloaterCamera::populatePresetCombo() { LLPresetsManager::getInstance()->setPresetNamesInComboBox(PRESETS_CAMERA, mPresetCombo, EDefaultOptions::DEFAULT_HIDE); diff --git a/indra/newview/llfloatercamera.h b/indra/newview/llfloatercamera.h index 269e4d1617..f718e8248d 100644 --- a/indra/newview/llfloatercamera.h +++ b/indra/newview/llfloatercamera.h @@ -70,10 +70,6 @@ public: /*switch to one of the camera presets (front, rear, side)*/ static void switchToPreset(const std::string& name); - /* move to CAMERA_CTRL_MODE_PRESETS from CAMERA_CTRL_MODE_FREE_CAMERA if we are on presets panel and - are not in free camera mode*/ - void fromFreeToPresets(); - virtual void onOpen(const LLSD& key); virtual void onClose(bool app_quitting); diff --git a/indra/newview/llfloatereditenvironmentbase.cpp b/indra/newview/llfloatereditenvironmentbase.cpp new file mode 100644 index 0000000000..1d28921878 --- /dev/null +++ b/indra/newview/llfloatereditenvironmentbase.cpp @@ -0,0 +1,479 @@ +/** + * @file llfloatereditenvironmentbase.cpp + * @brief Floaters to create and edit fixed settings for sky and water. + * + * $LicenseInfo:firstyear=2011&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2011, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llfloatereditenvironmentbase.h" + +#include + +// libs +#include "llnotifications.h" +#include "llnotificationsutil.h" +#include "llfilepicker.h" +#include "llsettingspicker.h" +#include "llviewerparcelmgr.h" + +// newview +#include "llsettingssky.h" +#include "llsettingswater.h" + +#include "llenvironment.h" +#include "llagent.h" +#include "llparcel.h" + +#include "llsettingsvo.h" +#include "llinventorymodel.h" + +namespace +{ + const std::string ACTION_APPLY_LOCAL("apply_local"); + const std::string ACTION_APPLY_PARCEL("apply_parcel"); + const std::string ACTION_APPLY_REGION("apply_region"); +} + +//========================================================================= +const std::string LLFloaterEditEnvironmentBase::KEY_INVENTORY_ID("inventory_id"); + + +//========================================================================= + +class LLFixedSettingCopiedCallback : public LLInventoryCallback +{ +public: + LLFixedSettingCopiedCallback(LLHandle handle) : mHandle(handle) {} + + virtual void fire(const LLUUID& inv_item_id) + { + if (!mHandle.isDead()) + { + LLViewerInventoryItem* item = gInventory.getItem(inv_item_id); + if (item) + { + LLFloaterEditEnvironmentBase* floater = (LLFloaterEditEnvironmentBase*)mHandle.get(); + floater->onInventoryCreated(item->getAssetUUID(), inv_item_id); + } + } + } + +private: + LLHandle mHandle; +}; + +//========================================================================= +LLFloaterEditEnvironmentBase::LLFloaterEditEnvironmentBase(const LLSD &key) : + LLFloater(key), + mInventoryId(), + mInventoryItem(nullptr), + mIsDirty(false), + mCanCopy(false), + mCanMod(false), + mCanTrans(false), + mCanSave(false) +{ +} + +LLFloaterEditEnvironmentBase::~LLFloaterEditEnvironmentBase() +{ +} + +void LLFloaterEditEnvironmentBase::onFocusReceived() +{ + if (isInVisibleChain()) + { + updateEditEnvironment(); + LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_EDIT, LLEnvironment::TRANSITION_FAST); + } +} + +void LLFloaterEditEnvironmentBase::onFocusLost() +{ +} + +void LLFloaterEditEnvironmentBase::loadInventoryItem(const LLUUID &inventoryId, bool can_trans) +{ + if (inventoryId.isNull()) + { + mInventoryItem = nullptr; + mInventoryId.setNull(); + mCanMod = true; + mCanCopy = true; + mCanTrans = true; + return; + } + + mInventoryId = inventoryId; + LL_INFOS("SETTINGS") << "Setting edit inventory item to " << mInventoryId << "." << LL_ENDL; + mInventoryItem = gInventory.getItem(mInventoryId); + + if (!mInventoryItem) + { + LL_WARNS("SETTINGS") << "Could not find inventory item with Id = " << mInventoryId << LL_ENDL; + LLNotificationsUtil::add("CantFindInvItem"); + closeFloater(); + + mInventoryId.setNull(); + mInventoryItem = nullptr; + return; + } + + if (mInventoryItem->getAssetUUID().isNull()) + { + LL_WARNS("ENVIRONMENT") << "Asset ID in inventory item is NULL (" << mInventoryId << ")" << LL_ENDL; + LLNotificationsUtil::add("UnableEditItem"); + closeFloater(); + + mInventoryId.setNull(); + mInventoryItem = nullptr; + return; + } + + mCanSave = true; + mCanCopy = mInventoryItem->getPermissions().allowCopyBy(gAgent.getID()); + mCanMod = mInventoryItem->getPermissions().allowModifyBy(gAgent.getID()); + mCanTrans = can_trans && mInventoryItem->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID()); + + mExpectingAssetId = mInventoryItem->getAssetUUID(); + LLSettingsVOBase::getSettingsAsset(mInventoryItem->getAssetUUID(), + [this](LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, LLExtStat) { onAssetLoaded(asset_id, settings, status); }); +} + + +void LLFloaterEditEnvironmentBase::checkAndConfirmSettingsLoss(LLFloaterEditEnvironmentBase::on_confirm_fn cb) +{ + if (isDirty()) + { + LLSD args(LLSDMap("TYPE", getEditSettings()->getSettingsType()) + ("NAME", getEditSettings()->getName())); + + // create and show confirmation textbox + LLNotificationsUtil::add("SettingsConfirmLoss", args, LLSD(), + [cb](const LLSD¬if, const LLSD&resp) + { + S32 opt = LLNotificationsUtil::getSelectedOption(notif, resp); + if (opt == 0) + cb(); + }); + } + else if (cb) + { + cb(); + } +} + +void LLFloaterEditEnvironmentBase::onAssetLoaded(LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status) +{ + if (asset_id != mExpectingAssetId) + { + LL_WARNS("ENVDAYEDIT") << "Expecting {" << mExpectingAssetId << "} got {" << asset_id << "} - throwing away." << LL_ENDL; + return; + } + mExpectingAssetId.setNull(); + clearDirtyFlag(); + + if (!settings || status) + { + LLSD args; + args["NAME"] = (mInventoryItem) ? mInventoryItem->getName() : asset_id.asString(); + LLNotificationsUtil::add("FailedToFindSettings", args); + closeFloater(); + return; + } + + if (settings->getFlag(LLSettingsBase::FLAG_NOSAVE)) + { + mCanSave = false; + mCanCopy = false; + mCanMod = false; + mCanTrans = false; + } + else + { + if (mInventoryItem) + settings->setName(mInventoryItem->getName()); + + if (mCanCopy) + settings->clearFlag(LLSettingsBase::FLAG_NOCOPY); + else + settings->setFlag(LLSettingsBase::FLAG_NOCOPY); + + if (mCanMod) + settings->clearFlag(LLSettingsBase::FLAG_NOMOD); + else + settings->setFlag(LLSettingsBase::FLAG_NOMOD); + + if (mCanTrans) + settings->clearFlag(LLSettingsBase::FLAG_NOTRANS); + else + settings->setFlag(LLSettingsBase::FLAG_NOTRANS); + } + + setEditSettingsAndUpdate(settings); +} + +void LLFloaterEditEnvironmentBase::onButtonImport() +{ + checkAndConfirmSettingsLoss([this](){ doImportFromDisk(); }); +} + +void LLFloaterEditEnvironmentBase::onSaveAsCommit(const LLSD& notification, const LLSD& response, const LLSettingsBase::ptr_t &settings) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + if (0 == option) + { + std::string settings_name = response["message"].asString(); + + LLInventoryObject::correctInventoryName(settings_name); + if (settings_name.empty()) + { + // Ideally notification should disable 'OK' button if name won't fit our requirements, + // for now either display notification, or use some default name + settings_name = "Unnamed"; + } + + if (mCanMod) + { + doApplyCreateNewInventory(settings_name, settings); + } + else if (mInventoryItem) + { + const LLUUID &marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false); + LLUUID parent_id = mInventoryItem->getParentUUID(); + if ((marketplacelistings_id == parent_id) || gInventory.isObjectDescendentOf(mInventoryItem->getUUID(), gInventory.getLibraryRootFolderID())) + { + parent_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS); + } + + LLPointer cb = new LLFixedSettingCopiedCallback(getHandle()); + copy_inventory_item( + gAgent.getID(), + mInventoryItem->getPermissions().getOwner(), + mInventoryItem->getUUID(), + parent_id, + settings_name, + cb); + } + else + { + LL_WARNS() << "Failed to copy fixed env setting" << LL_ENDL; + } + } +} + +void LLFloaterEditEnvironmentBase::onClickCloseBtn(bool app_quitting) +{ + if (!app_quitting) + checkAndConfirmSettingsLoss([this](){ closeFloater(); clearDirtyFlag(); }); + else + closeFloater(); +} + +void LLFloaterEditEnvironmentBase::doApplyCreateNewInventory(std::string settings_name, const LLSettingsBase::ptr_t &settings) +{ + if (mInventoryItem) + { + LLUUID parent_id = mInventoryItem->getParentUUID(); + U32 next_owner_perm = mInventoryItem->getPermissions().getMaskNextOwner(); + LLSettingsVOBase::createInventoryItem(settings, next_owner_perm, parent_id, settings_name, + [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryCreated(asset_id, inventory_id, results); }); + } + else + { + LLUUID parent_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS); + // This method knows what sort of settings object to create. + LLSettingsVOBase::createInventoryItem(settings, parent_id, settings_name, + [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryCreated(asset_id, inventory_id, results); }); + } +} + +void LLFloaterEditEnvironmentBase::doApplyUpdateInventory(const LLSettingsBase::ptr_t &settings) +{ + LL_DEBUGS("ENVEDIT") << "Update inventory for " << mInventoryId << LL_ENDL; + if (mInventoryId.isNull()) + { + LLSettingsVOBase::createInventoryItem(settings, gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS), std::string(), + [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryCreated(asset_id, inventory_id, results); }); + } + else + { + LLSettingsVOBase::updateInventoryItem(settings, mInventoryId, + [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryUpdated(asset_id, inventory_id, results); }); + } +} + +void LLFloaterEditEnvironmentBase::doApplyEnvironment(const std::string &where, const LLSettingsBase::ptr_t &settings) +{ + U32 flags(0); + + if (mInventoryItem) + { + if (!mInventoryItem->getPermissions().allowOperationBy(PERM_MODIFY, gAgent.getID())) + flags |= LLSettingsBase::FLAG_NOMOD; + if (!mInventoryItem->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID())) + flags |= LLSettingsBase::FLAG_NOTRANS; + } + + flags |= settings->getFlags(); + settings->setFlag(flags); + + if (where == ACTION_APPLY_LOCAL) + { + settings->setName("Local"); // To distinguish and make sure there is a name. Safe, because this is a copy. + LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, settings); + } + else if (where == ACTION_APPLY_PARCEL) + { + LLParcel *parcel(LLViewerParcelMgr::instance().getAgentOrSelectedParcel()); + + if ((!parcel) || (parcel->getLocalID() == INVALID_PARCEL_ID)) + { + LL_WARNS("ENVIRONMENT") << "Can not identify parcel. Not applying." << LL_ENDL; + LLNotificationsUtil::add("WLParcelApplyFail"); + return; + } + + if (mInventoryItem && !isDirty()) + { + LLEnvironment::instance().updateParcel(parcel->getLocalID(), mInventoryItem->getAssetUUID(), mInventoryItem->getName(), LLEnvironment::NO_TRACK, -1, -1, flags); + } + else if (settings->getSettingsType() == "sky") + { + LLEnvironment::instance().updateParcel(parcel->getLocalID(), std::static_pointer_cast(settings), -1, -1); + } + else if (settings->getSettingsType() == "water") + { + LLEnvironment::instance().updateParcel(parcel->getLocalID(), std::static_pointer_cast(settings), -1, -1); + } + else if (settings->getSettingsType() == "day") + { + LLEnvironment::instance().updateParcel(parcel->getLocalID(), std::static_pointer_cast(settings), -1, -1); + } + } + else if (where == ACTION_APPLY_REGION) + { + if (mInventoryItem && !isDirty()) + { + LLEnvironment::instance().updateRegion(mInventoryItem->getAssetUUID(), mInventoryItem->getName(), LLEnvironment::NO_TRACK, -1, -1, flags); + } + else if (settings->getSettingsType() == "sky") + { + LLEnvironment::instance().updateRegion(std::static_pointer_cast(settings), -1, -1); + } + else if (settings->getSettingsType() == "water") + { + LLEnvironment::instance().updateRegion(std::static_pointer_cast(settings), -1, -1); + } + else if (settings->getSettingsType() == "day") + { + LLEnvironment::instance().updateRegion(std::static_pointer_cast(settings), -1, -1); + } + } + else + { + LL_WARNS("ENVIRONMENT") << "Unknown apply '" << where << "'" << LL_ENDL; + return; + } + +} + +void LLFloaterEditEnvironmentBase::doCloseInventoryFloater(bool quitting) +{ + LLFloater* floaterp = mInventoryFloater.get(); + + if (floaterp) + { + floaterp->closeFloater(quitting); + } +} + +void LLFloaterEditEnvironmentBase::onInventoryCreated(LLUUID asset_id, LLUUID inventory_id, LLSD results) +{ + LL_WARNS("ENVIRONMENT") << "Inventory item " << inventory_id << " has been created with asset " << asset_id << " results are:" << results << LL_ENDL; + + if (inventory_id.isNull() || !results["success"].asBoolean()) + { + LLNotificationsUtil::add("CantCreateInventory"); + return; + } + onInventoryCreated(asset_id, inventory_id); +} + +void LLFloaterEditEnvironmentBase::onInventoryCreated(LLUUID asset_id, LLUUID inventory_id) +{ + bool can_trans = true; + if (mInventoryItem) + { + LLPermissions perms = mInventoryItem->getPermissions(); + + LLInventoryItem *created_item = gInventory.getItem(mInventoryId); + + if (created_item) + { + can_trans = perms.allowOperationBy(PERM_TRANSFER, gAgent.getID()); + created_item->setPermissions(perms); + created_item->updateServer(false); + } + } + + clearDirtyFlag(); + setFocus(TRUE); // Call back the focus... + loadInventoryItem(inventory_id, can_trans); +} + +void LLFloaterEditEnvironmentBase::onInventoryUpdated(LLUUID asset_id, LLUUID inventory_id, LLSD results) +{ + LL_WARNS("ENVIRONMENT") << "Inventory item " << inventory_id << " has been updated with asset " << asset_id << " results are:" << results << LL_ENDL; + + clearDirtyFlag(); + if (inventory_id != mInventoryId) + { + loadInventoryItem(inventory_id); + } +} + +void LLFloaterEditEnvironmentBase::onPanelDirtyFlagChanged(bool value) +{ + if (value) + setDirtyFlag(); +} + +//------------------------------------------------------------------------- +bool LLFloaterEditEnvironmentBase::canUseInventory() const +{ + return LLEnvironment::instance().isInventoryEnabled(); +} + +bool LLFloaterEditEnvironmentBase::canApplyRegion() const +{ + return gAgent.canManageEstate(); +} + +bool LLFloaterEditEnvironmentBase::canApplyParcel() const +{ + return LLEnvironment::instance().canAgentUpdateParcelEnvironment(); +} + +//========================================================================= diff --git a/indra/newview/llfloatereditenvironmentbase.h b/indra/newview/llfloatereditenvironmentbase.h new file mode 100644 index 0000000000..7c7cf5bdcd --- /dev/null +++ b/indra/newview/llfloatereditenvironmentbase.h @@ -0,0 +1,148 @@ +/** + * @file llfloatereditenvironmentbase.h + * @brief Floaters to create and edit fixed settings for sky and water. + * + * $LicenseInfo:firstyear=2011&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2011, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_FLOATEREDITENVIRONMENTBASE_H +#define LL_FLOATEREDITENVIRONMENTBASE_H + +#include "llfloater.h" +#include "llsettingsbase.h" +#include "llflyoutcombobtn.h" +#include "llinventory.h" + +#include "boost/signals2.hpp" + +class LLTabContainer; +class LLButton; +class LLLineEditor; +class LLFloaterSettingsPicker; +class LLFixedSettingCopiedCallback; + +class LLFloaterEditEnvironmentBase : public LLFloater +{ + LOG_CLASS(LLFloaterEditEnvironmentBase); + + friend class LLFixedSettingCopiedCallback; + +public: + static const std::string KEY_INVENTORY_ID; + + LLFloaterEditEnvironmentBase(const LLSD &key); + ~LLFloaterEditEnvironmentBase(); + + virtual void onFocusReceived() override; + virtual void onFocusLost() override; + + virtual LLSettingsBase::ptr_t getEditSettings() const = 0; + + virtual BOOL isDirty() const override { return getIsDirty(); } + +protected: + typedef std::function on_confirm_fn; + + virtual void setEditSettingsAndUpdate(const LLSettingsBase::ptr_t &settings) = 0; + virtual void updateEditEnvironment() = 0; + + virtual LLFloaterSettingsPicker *getSettingsPicker() = 0; + + void loadInventoryItem(const LLUUID &inventoryId, bool can_trans = true); + + void checkAndConfirmSettingsLoss(on_confirm_fn cb); + + virtual void doImportFromDisk() = 0; + virtual void doApplyCreateNewInventory(std::string settings_name, const LLSettingsBase::ptr_t &settings); + virtual void doApplyUpdateInventory(const LLSettingsBase::ptr_t &settings); + virtual void doApplyEnvironment(const std::string &where, const LLSettingsBase::ptr_t &settings); + void doCloseInventoryFloater(bool quitting = false); + + bool canUseInventory() const; + bool canApplyRegion() const; + bool canApplyParcel() const; + + LLUUID mInventoryId; + LLInventoryItem * mInventoryItem; + LLHandle mInventoryFloater; + bool mCanCopy; + bool mCanMod; + bool mCanTrans; + bool mCanSave; + + bool mIsDirty; + + void onInventoryCreated(LLUUID asset_id, LLUUID inventory_id); + void onInventoryCreated(LLUUID asset_id, LLUUID inventory_id, LLSD results); + void onInventoryUpdated(LLUUID asset_id, LLUUID inventory_id, LLSD results); + + bool getIsDirty() const { return mIsDirty; } + void setDirtyFlag() { mIsDirty = true; } + virtual void clearDirtyFlag() = 0; + + void onPanelDirtyFlagChanged(bool); + + virtual void onClickCloseBtn(bool app_quitting = false) override; + void onSaveAsCommit(const LLSD& notification, const LLSD& response, const LLSettingsBase::ptr_t &settings); + void onButtonImport(); + + void onAssetLoaded(LLUUID asset_id, LLSettingsBase::ptr_t settins, S32 status); + +private: + LLUUID mExpectingAssetId; // for asset load confirmation +}; + +class LLSettingsEditPanel : public LLPanel +{ +public: + virtual void setSettings(const LLSettingsBase::ptr_t &) = 0; + + typedef boost::signals2::signal on_dirty_charged_sg; + typedef boost::signals2::connection connection_t; + + inline bool getIsDirty() const { return mIsDirty; } + inline void setIsDirty() { mIsDirty = true; if (!mOnDirtyChanged.empty()) mOnDirtyChanged(this, mIsDirty); } + inline void clearIsDirty() { mIsDirty = false; if (!mOnDirtyChanged.empty()) mOnDirtyChanged(this, mIsDirty); } + + inline bool getCanChangeSettings() const { return mCanEdit; } + inline void setCanChangeSettings(bool flag) { mCanEdit = flag; } + + inline connection_t setOnDirtyFlagChanged(on_dirty_charged_sg::slot_type cb) { return mOnDirtyChanged.connect(cb); } + + +protected: + LLSettingsEditPanel() : + LLPanel(), + mIsDirty(false), + mOnDirtyChanged() + {} + +private: + void onTextureChanged(LLUUID &inventory_item_id); + + bool mIsDirty; + bool mCanEdit; + + on_dirty_charged_sg mOnDirtyChanged; +}; + +#endif // LL_FLOATERENVIRONMENTBASE_H diff --git a/indra/newview/llfloatereditextdaycycle.cpp b/indra/newview/llfloatereditextdaycycle.cpp index a7c2cbbeaa..0501c287ad 100644 --- a/indra/newview/llfloatereditextdaycycle.cpp +++ b/indra/newview/llfloatereditextdaycycle.cpp @@ -125,7 +125,6 @@ namespace { } //========================================================================= -const std::string LLFloaterEditExtDayCycle::KEY_INVENTORY_ID("inventory_id"); const std::string LLFloaterEditExtDayCycle::KEY_EDIT_CONTEXT("edit_context"); const std::string LLFloaterEditExtDayCycle::KEY_DAY_LENGTH("day_length"); const std::string LLFloaterEditExtDayCycle::KEY_CANMOD("canmod"); @@ -133,7 +132,7 @@ const std::string LLFloaterEditExtDayCycle::KEY_CANMOD("canmod"); const std::string LLFloaterEditExtDayCycle::VALUE_CONTEXT_INVENTORY("inventory"); const std::string LLFloaterEditExtDayCycle::VALUE_CONTEXT_PARCEL("parcel"); const std::string LLFloaterEditExtDayCycle::VALUE_CONTEXT_REGION("region"); - +/* //========================================================================= class LLDaySettingCopiedCallback : public LLInventoryCallback @@ -156,12 +155,12 @@ public: private: LLHandle mHandle; -}; +};*/ //========================================================================= LLFloaterEditExtDayCycle::LLFloaterEditExtDayCycle(const LLSD &key) : - LLFloater(key), + LLFloaterEditEnvironmentBase(key), mFlyoutControl(nullptr), mDayLength(0), mCurrentTrack(1), @@ -170,19 +169,12 @@ LLFloaterEditExtDayCycle::LLFloaterEditExtDayCycle(const LLSD &key) : mFramesSlider(nullptr), mCurrentTimeLabel(nullptr), mImportButton(nullptr), - mInventoryId(), - mInventoryItem(nullptr), mLoadFrame(nullptr), mSkyBlender(), mWaterBlender(), mScratchSky(), mScratchWater(), mIsPlaying(false), - mIsDirty(false), - mCanSave(false), - mCanCopy(false), - mCanMod(false), - mCanTrans(false), mCloneTrack(nullptr), mLoadTrack(nullptr), mClearTrack(nullptr) @@ -425,19 +417,6 @@ void LLFloaterEditExtDayCycle::onClose(bool app_quitting) } } -void LLFloaterEditExtDayCycle::onFocusReceived() -{ - if (isInVisibleChain()) - { - updateEditEnvironment(); - LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_EDIT, LLEnvironment::TRANSITION_FAST); - } -} - -void LLFloaterEditExtDayCycle::onFocusLost() -{ -} - void LLFloaterEditExtDayCycle::onVisibilityChange(BOOL new_visibility) { @@ -488,6 +467,10 @@ void LLFloaterEditExtDayCycle::refresh() LLFloater::refresh(); } +void LLFloaterEditExtDayCycle::setEditSettingsAndUpdate(const LLSettingsBase::ptr_t &settings) +{ + setEditDayCycle(std::dynamic_pointer_cast(settings)); +} void LLFloaterEditExtDayCycle::setEditDayCycle(const LLSettingsDay::ptr_t &pday) { @@ -700,63 +683,6 @@ void LLFloaterEditExtDayCycle::onButtonApply(LLUICtrl *ctrl, const LLSD &data) } } -void LLFloaterEditExtDayCycle::onSaveAsCommit(const LLSD& notification, const LLSD& response, const LLSettingsDay::ptr_t &day) -{ - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - if (0 == option) - { - std::string settings_name = response["message"].asString(); - - LLInventoryObject::correctInventoryName(settings_name); - if (settings_name.empty()) - { - // Ideally notification should disable 'OK' button if name won't fit our requirements, - // for now either display notification, or use some default name - settings_name = "Unnamed"; - } - - if (mCanMod) - { - doApplyCreateNewInventory(day, settings_name); - } - else if (mInventoryItem) - { - const LLUUID &marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false); - LLUUID parent_id = mInventoryItem->getParentUUID(); - if (marketplacelistings_id == parent_id) - { - parent_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS); - } - - LLPointer cb = new LLDaySettingCopiedCallback(getHandle()); - copy_inventory_item( - gAgent.getID(), - mInventoryItem->getPermissions().getOwner(), - mInventoryItem->getUUID(), - parent_id, - settings_name, - cb); - } - else - { - LL_WARNS() << "Failed to copy day setting" << LL_ENDL; - } - } -} - -void LLFloaterEditExtDayCycle::onClickCloseBtn(bool app_quitting /*= false*/) -{ - if (!app_quitting) - checkAndConfirmSettingsLoss([this](){ closeFloater(); clearDirtyFlag(); }); - else - closeFloater(); -} - -void LLFloaterEditExtDayCycle::onButtonImport() -{ - checkAndConfirmSettingsLoss([this]() { doImportFromDisk(); }); -} - void LLFloaterEditExtDayCycle::onButtonLoadFrame() { doOpenInventoryFloater((mCurrentTrack == LLSettingsDay::TRACK_WATER) ? LLSettingsType::ST_WATER : LLSettingsType::ST_SKY, LLUUID::null); @@ -1053,35 +979,6 @@ void LLFloaterEditExtDayCycle::onFrameSliderMouseUp(S32 x, S32 y, MASK mask) selectFrame(sliderpos, LLSettingsDay::DEFAULT_FRAME_SLOP_FACTOR); } - -void LLFloaterEditExtDayCycle::onPanelDirtyFlagChanged(bool value) -{ - if (value) - setDirtyFlag(); -} - -void LLFloaterEditExtDayCycle::checkAndConfirmSettingsLoss(on_confirm_fn cb) -{ - if (isDirty()) - { - LLSD args(LLSDMap("TYPE", mEditDay->getSettingsType()) - ("NAME", mEditDay->getName())); - - // create and show confirmation textbox - LLNotificationsUtil::add("SettingsConfirmLoss", args, LLSD(), - [cb](const LLSD¬if, const LLSD&resp) - { - S32 opt = LLNotificationsUtil::getSelectedOption(notif, resp); - if (opt == 0) - cb(); - }); - } - else if (cb) - { - cb(); - } -} - void LLFloaterEditExtDayCycle::onTimeSliderCallback() { stopPlay(); @@ -1435,106 +1332,6 @@ LLFloaterEditExtDayCycle::connection_t LLFloaterEditExtDayCycle::setEditCommitSi return mCommitSignal.connect(cb); } -void LLFloaterEditExtDayCycle::loadInventoryItem(const LLUUID &inventoryId, bool can_trans) -{ - if (inventoryId.isNull()) - { - mInventoryItem = nullptr; - mInventoryId.setNull(); - mCanSave = true; - mCanCopy = true; - mCanMod = true; - mCanTrans = true; - return; - } - - mInventoryId = inventoryId; - LL_INFOS("ENVDAYEDIT") << "Setting edit inventory item to " << mInventoryId << "." << LL_ENDL; - mInventoryItem = gInventory.getItem(mInventoryId); - - if (!mInventoryItem) - { - LL_WARNS("ENVDAYEDIT") << "Could not find inventory item with Id = " << mInventoryId << LL_ENDL; - - LLNotificationsUtil::add("CantFindInvItem"); - closeFloater(); - mInventoryId.setNull(); - mInventoryItem = nullptr; - return; - } - - if (mInventoryItem->getAssetUUID().isNull()) - { - LL_WARNS("ENVDAYEDIT") << "Asset ID in inventory item is NULL (" << mInventoryId << ")" << LL_ENDL; - - LLNotificationsUtil::add("UnableEditItem"); - closeFloater(); - - mInventoryId.setNull(); - mInventoryItem = nullptr; - return; - } - - mCanSave = true; - mCanCopy = mInventoryItem->getPermissions().allowCopyBy(gAgent.getID()); - mCanMod = mInventoryItem->getPermissions().allowModifyBy(gAgent.getID()); - mCanTrans = can_trans && mInventoryItem->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID()); - - mExpectingAssetId = mInventoryItem->getAssetUUID(); - LLSettingsVOBase::getSettingsAsset(mInventoryItem->getAssetUUID(), - [this](LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, LLExtStat) { onAssetLoaded(asset_id, settings, status); }); -} - -void LLFloaterEditExtDayCycle::onAssetLoaded(LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status) -{ - if (asset_id != mExpectingAssetId) - { - LL_WARNS("ENVDAYEDIT") << "Expecting {" << mExpectingAssetId << "} got {" << asset_id << "} - throwing away." << LL_ENDL; - return; - } - mExpectingAssetId.setNull(); - clearDirtyFlag(); - - if (!settings || status) - { - LLSD args; - args["NAME"] = (mInventoryItem) ? mInventoryItem->getName() : asset_id.asString(); - LLNotificationsUtil::add("FailedToFindSettings", args); - closeFloater(); - return; - } - - if (settings->getFlag(LLSettingsBase::FLAG_NOSAVE)) - { - mCanSave = false; - mCanCopy = false; - mCanMod = false; - mCanTrans = false; - } - else - { - if (mCanCopy) - settings->clearFlag(LLSettingsBase::FLAG_NOCOPY); - else - settings->setFlag(LLSettingsBase::FLAG_NOCOPY); - - if (mCanMod) - settings->clearFlag(LLSettingsBase::FLAG_NOMOD); - else - settings->setFlag(LLSettingsBase::FLAG_NOMOD); - - if (mCanTrans) - settings->clearFlag(LLSettingsBase::FLAG_NOTRANS); - else - settings->setFlag(LLSettingsBase::FLAG_NOTRANS); - - if (mInventoryItem) - settings->setName(mInventoryItem->getName()); - } - - setEditDayCycle(std::dynamic_pointer_cast(settings)); -} - void LLFloaterEditExtDayCycle::updateEditEnvironment(void) { if (!mEditDay) @@ -1670,93 +1467,6 @@ void LLFloaterEditExtDayCycle::reblendSettings() mWaterBlender->setPosition(position); } -void LLFloaterEditExtDayCycle::doApplyCreateNewInventory(const LLSettingsDay::ptr_t &day, std::string settings_name) -{ - if (mInventoryItem) - { - LLUUID parent_id = mInventoryItem->getParentUUID(); - U32 next_owner_perm = mInventoryItem->getPermissions().getMaskNextOwner(); - LLSettingsVOBase::createInventoryItem(day, next_owner_perm, parent_id, settings_name, - [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryCreated(asset_id, inventory_id, results); }); - } - else - { - LLUUID parent_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS); - // This method knows what sort of settings object to create. - LLSettingsVOBase::createInventoryItem(day, parent_id, settings_name, - [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryCreated(asset_id, inventory_id, results); }); - } -} - -void LLFloaterEditExtDayCycle::doApplyUpdateInventory(const LLSettingsDay::ptr_t &day) -{ - if (mInventoryId.isNull()) - LLSettingsVOBase::createInventoryItem(day, gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS), std::string(), - [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryCreated(asset_id, inventory_id, results); }); - else - LLSettingsVOBase::updateInventoryItem(day, mInventoryId, - [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryUpdated(asset_id, inventory_id, results); }); -} - -void LLFloaterEditExtDayCycle::doApplyEnvironment(const std::string &where, const LLSettingsDay::ptr_t &day) -{ - U32 flags(0); - - if (mInventoryItem) - { - if (!mInventoryItem->getPermissions().allowOperationBy(PERM_MODIFY, gAgent.getID())) - flags |= LLSettingsBase::FLAG_NOMOD; - if (!mInventoryItem->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID())) - flags |= LLSettingsBase::FLAG_NOTRANS; - } - - flags |= day->getFlags(); - day->setFlag(flags); - - if (where == ACTION_APPLY_LOCAL) - { - day->setName("Local"); // To distinguish and make sure there is a name. Safe, because this is a copy. - LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, day); - } - else if (where == ACTION_APPLY_PARCEL) - { - LLParcel *parcel(LLViewerParcelMgr::instance().getAgentOrSelectedParcel()); - - if ((!parcel) || (parcel->getLocalID() == INVALID_PARCEL_ID)) - { - LL_WARNS("ENVDAYEDIT") << "Can not identify parcel. Not applying." << LL_ENDL; - LLNotificationsUtil::add("WLParcelApplyFail"); - return; - } - - if (mInventoryItem && !isDirty()) - { - LLEnvironment::instance().updateParcel(parcel->getLocalID(), mInventoryItem->getAssetUUID(), mInventoryItem->getName(), LLEnvironment::NO_TRACK, -1, -1, flags); - } - else - { - LLEnvironment::instance().updateParcel(parcel->getLocalID(), day, -1, -1); - } - } - else if (where == ACTION_APPLY_REGION) - { - if (mInventoryItem && !isDirty()) - { - LLEnvironment::instance().updateRegion(mInventoryItem->getAssetUUID(), mInventoryItem->getName(), LLEnvironment::NO_TRACK, -1, -1, flags); - } - else - { - LLEnvironment::instance().updateRegion(day, -1, -1); - } - } - else - { - LL_WARNS("ENVDAYEDIT") << "Unknown apply '" << where << "'" << LL_ENDL; - return; - } - -} - void LLFloaterEditExtDayCycle::doApplyCommit(LLSettingsDay::ptr_t day) { if (!mCommitSignal.empty()) @@ -1793,51 +1503,6 @@ bool LLFloaterEditExtDayCycle::isAddingFrameAllowed() return mFramesSlider->canAddSliders(); } -void LLFloaterEditExtDayCycle::onInventoryCreated(LLUUID asset_id, LLUUID inventory_id, LLSD results) -{ - LL_INFOS("ENVDAYEDIT") << "Inventory item " << inventory_id << " has been created with asset " << asset_id << " results are:" << results << LL_ENDL; - - if (inventory_id.isNull() || !results["success"].asBoolean()) - { - LLNotificationsUtil::add("CantCreateInventory"); - return; - } - onInventoryCreated(asset_id, inventory_id); -} - -void LLFloaterEditExtDayCycle::onInventoryCreated(LLUUID asset_id, LLUUID inventory_id) -{ - bool can_trans = true; - if (mInventoryItem) - { - LLPermissions perms = mInventoryItem->getPermissions(); - - LLInventoryItem *created_item = gInventory.getItem(mInventoryId); - - if (created_item) - { - can_trans = perms.allowOperationBy(PERM_TRANSFER, gAgent.getID()); - created_item->setPermissions(perms); - created_item->updateServer(false); - } - } - - clearDirtyFlag(); - setFocus(TRUE); // Call back the focus... - loadInventoryItem(inventory_id, can_trans); -} - -void LLFloaterEditExtDayCycle::onInventoryUpdated(LLUUID asset_id, LLUUID inventory_id, LLSD results) -{ - LL_WARNS("ENVDAYEDIT") << "Inventory item " << inventory_id << " has been updated with asset " << asset_id << " results are:" << results << LL_ENDL; - - clearDirtyFlag(); - if (inventory_id != mInventoryId) - { - loadInventoryItem(inventory_id); - } -} - void LLFloaterEditExtDayCycle::doImportFromDisk() { // Load a a legacy Windlight XML from disk. (new LLFilePickerReplyThread(boost::bind(&LLFloaterEditExtDayCycle::loadSettingFromFile, this, _1), LLFilePicker::FFLOAD_XML, false))->getFile(); @@ -1864,21 +1529,6 @@ void LLFloaterEditExtDayCycle::loadSettingFromFile(const std::vectorsetCursor(UI_CURSOR_WAIT); LLFloaterSettingsPicker *picker = static_cast(mInventoryFloater.get()); // Show the dialog @@ -2003,7 +1647,17 @@ void LLFloaterEditExtDayCycle::doOpenInventoryFloater(LLSettingsType::type_e typ picker->setCommitCallback([this](LLUICtrl *, const LLSD &data){ onPickerCommitSetting(data["ItemId"].asUUID(), data["Track"].asInteger()); }); } + return picker; +} +void LLFloaterEditExtDayCycle::onPickerCommitTrackId(U32 track_id) +{ + cloneTrack(track_id, mCurrentTrack); +} + +void LLFloaterEditExtDayCycle::doOpenInventoryFloater(LLSettingsType::type_e type, LLUUID curritem) +{ + LLFloaterSettingsPicker *picker = getSettingsPicker(); picker->setSettingsFilter(type); picker->setSettingsItemId(curritem); if (type == LLSettingsType::ST_DAYCYCLE) @@ -2018,16 +1672,6 @@ void LLFloaterEditExtDayCycle::doOpenInventoryFloater(LLSettingsType::type_e typ picker->setFocus(TRUE); } -void LLFloaterEditExtDayCycle::doCloseInventoryFloater(bool quitting) -{ - LLFloater* floaterp = mInventoryFloater.get(); - - if (floaterp) - { - floaterp->closeFloater(quitting); - } -} - void LLFloaterEditExtDayCycle::onPickerCommitSetting(LLUUID item_id, S32 track) { LLSettingsBase::TrackPosition frame(mTimeSlider->getCurSliderValue()); @@ -2118,7 +1762,9 @@ void LLFloaterEditExtDayCycle::onAssetLoadedForInsertion(LLUUID item_id, LLUUID LLInventoryItem *inv_item = gInventory.getItem(item_id); - if (inv_item && !inv_item->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID())) + if (inv_item + && (!inv_item->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID()) + || !inv_item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID()))) { // Need to check if item is already no-transfer, otherwise make it no-transfer bool no_transfer = false; diff --git a/indra/newview/llfloatereditextdaycycle.h b/indra/newview/llfloatereditextdaycycle.h index b6e9fdb14f..9a30fb199f 100644 --- a/indra/newview/llfloatereditextdaycycle.h +++ b/indra/newview/llfloatereditextdaycycle.h @@ -32,6 +32,7 @@ #include #include "llenvironment.h" +#include "llfloatereditenvironmentbase.h" class LLCheckBoxCtrl; class LLComboBox; @@ -50,14 +51,13 @@ typedef std::shared_ptr LLSettingsBasePtr_t; /** * Floater for creating or editing a day cycle. */ -class LLFloaterEditExtDayCycle : public LLFloater +class LLFloaterEditExtDayCycle : public LLFloaterEditEnvironmentBase { LOG_CLASS(LLFloaterEditExtDayCycle); friend class LLDaySettingCopiedCallback; public: - static const std::string KEY_INVENTORY_ID; static const std::string KEY_EDIT_CONTEXT; static const std::string KEY_DAY_LENGTH; static const std::string KEY_CANMOD; @@ -82,8 +82,8 @@ public: virtual BOOL postBuild() override; virtual void onOpen(const LLSD& key) override; virtual void onClose(bool app_quitting) override; - virtual void onFocusReceived() override; - virtual void onFocusLost() override; + //virtual void onFocusReceived() override; + //virtual void onFocusLost() override; virtual void onVisibilityChange(BOOL new_visibility) override; connection_t setEditCommitSignal(edit_commit_signal_t::slot_type cb); @@ -97,10 +97,13 @@ public: LLUUID getEditingAssetId() { return mEditDay ? mEditDay->getAssetId() : LLUUID::null; } LLUUID getEditingInventoryId() { return mInventoryId; } + virtual LLSettingsBase::ptr_t getEditSettings() const override { return mEditDay; } + BOOL handleKeyUp(KEY key, MASK mask, BOOL called_from_parent) override; - BOOL isDirty() const override { return getIsDirty(); } +protected: + virtual void setEditSettingsAndUpdate(const LLSettingsBase::ptr_t &settings) override; private: typedef std::function on_confirm_fn; @@ -108,8 +111,8 @@ private: // flyout response/click void onButtonApply(LLUICtrl *ctrl, const LLSD &data); - virtual void onClickCloseBtn(bool app_quitting = false) override; - void onButtonImport(); + //virtual void onClickCloseBtn(bool app_quitting = false) override; + //void onButtonImport(); void onButtonLoadFrame(); void onAddFrame(); void onRemoveFrame(); @@ -119,7 +122,6 @@ private: void onCommitName(class LLLineEditor* caller, void* user_data); void onTrackSelectionCallback(const LLSD& user_data); void onPlayActionCallback(const LLSD& user_data); - void onSaveAsCommit(const LLSD& notification, const LLSD& response, const LLSettingsDay::ptr_t &day); // time slider clicked void onTimeSliderCallback(); // a frame moved or frame selection changed @@ -128,10 +130,6 @@ private: void onFrameSliderMouseDown(S32 x, S32 y, MASK mask); void onFrameSliderMouseUp(S32 x, S32 y, MASK mask); - void onPanelDirtyFlagChanged(bool); - - void checkAndConfirmSettingsLoss(on_confirm_fn cb); - void cloneTrack(U32 source_index, U32 dest_index); void cloneTrack(const LLSettingsDay::ptr_t &source_day, U32 source_index, U32 dest_index); void selectTrack(U32 track_index, bool force = false); @@ -148,25 +146,21 @@ private: void removeCurrentSliderFrame(); void removeSliderFrame(F32 frame); - void loadInventoryItem(const LLUUID &inventoryId, bool can_trans = true); - void onAssetLoaded(LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status); - - void doImportFromDisk(); + virtual void doImportFromDisk() override; void loadSettingFromFile(const std::vector& filenames); - void doApplyCreateNewInventory(const LLSettingsDay::ptr_t &day, std::string settings_name); - void doApplyUpdateInventory(const LLSettingsDay::ptr_t &day); - void doApplyEnvironment(const std::string &where, const LLSettingsDay::ptr_t &day); void doApplyCommit(LLSettingsDay::ptr_t day); void onInventoryCreated(LLUUID asset_id, LLUUID inventory_id); void onInventoryCreated(LLUUID asset_id, LLUUID inventory_id, LLSD results); void onInventoryUpdated(LLUUID asset_id, LLUUID inventory_id, LLSD results); + void doOpenTrackFloater(const LLSD &args); void doCloseTrackFloater(bool quitting = false); + virtual LLFloaterSettingsPicker* getSettingsPicker() override; void onPickerCommitTrackId(U32 track_id); void doOpenInventoryFloater(LLSettingsType::type_e type, LLUUID curritem); - void doCloseInventoryFloater(bool quitting = false); + //void doCloseInventoryFloater(bool quitting = false); void onPickerCommitSetting(LLUUID item_id, S32 track); void onAssetLoadedForInsertion(LLUUID item_id, LLUUID asset_id, @@ -176,11 +170,7 @@ private: S32 dest_track, LLSettingsBase::TrackPosition dest_frame); - bool canUseInventory() const; - bool canApplyRegion() const; - bool canApplyParcel() const; - - void updateEditEnvironment(); + virtual void updateEditEnvironment() override; void synchronizeTabs(); void reblendSettings(); @@ -193,7 +183,7 @@ private: bool getIsDirty() const { return mIsDirty; } void setDirtyFlag() { mIsDirty = true; } - virtual void clearDirtyFlag(); + virtual void clearDirtyFlag() override; bool isRemovingFrameAllowed(); bool isAddingFrameAllowed(); @@ -218,11 +208,8 @@ private: LLView* mSkyTabLayoutContainer; LLView* mWaterTabLayoutContainer; LLTextBox* mCurrentTimeLabel; - LLUUID mInventoryId; - LLInventoryItem * mInventoryItem; LLFlyoutComboBtnCtrl * mFlyoutControl; - LLHandle mInventoryFloater; LLHandle mTrackFloater; LLTrackBlenderLoopingManual::ptr_t mSkyBlender; @@ -236,11 +223,6 @@ private: LLFrameTimer mPlayTimer; F32 mPlayStartFrame; // an env frame bool mIsPlaying; - bool mIsDirty; - bool mCanCopy; - bool mCanMod; - bool mCanTrans; - bool mCanSave; edit_commit_signal_t mCommitSignal; diff --git a/indra/newview/llfloaterfixedenvironment.cpp b/indra/newview/llfloaterfixedenvironment.cpp index 327314969a..41bbd5e8f9 100644 --- a/indra/newview/llfloaterfixedenvironment.cpp +++ b/indra/newview/llfloaterfixedenvironment.cpp @@ -81,44 +81,11 @@ namespace const std::string XML_FLYOUTMENU_FILE("menu_save_settings.xml"); } -//========================================================================= -const std::string LLFloaterFixedEnvironment::KEY_INVENTORY_ID("inventory_id"); - - -//========================================================================= - -class LLFixedSettingCopiedCallback : public LLInventoryCallback -{ -public: - LLFixedSettingCopiedCallback(LLHandle handle) : mHandle(handle) {} - - virtual void fire(const LLUUID& inv_item_id) - { - if (!mHandle.isDead()) - { - LLViewerInventoryItem* item = gInventory.getItem(inv_item_id); - if (item) - { - LLFloaterFixedEnvironment* floater = (LLFloaterFixedEnvironment*)mHandle.get(); - floater->onInventoryCreated(item->getAssetUUID(), inv_item_id); - } - } - } - -private: - LLHandle mHandle; -}; //========================================================================= LLFloaterFixedEnvironment::LLFloaterFixedEnvironment(const LLSD &key) : - LLFloater(key), - mFlyoutControl(nullptr), - mInventoryId(), - mInventoryItem(nullptr), - mIsDirty(false), - mCanCopy(false), - mCanMod(false), - mCanTrans(false) + LLFloaterEditEnvironmentBase(key), + mFlyoutControl(nullptr) { } @@ -176,19 +143,6 @@ void LLFloaterFixedEnvironment::onClose(bool app_quitting) syncronizeTabs(); } -void LLFloaterFixedEnvironment::onFocusReceived() -{ - if (isInVisibleChain()) - { - updateEditEnvironment(); - LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_EDIT, LLEnvironment::TRANSITION_FAST); - } -} - -void LLFloaterFixedEnvironment::onFocusLost() -{ -} - void LLFloaterFixedEnvironment::refresh() { if (!mSettings) @@ -220,6 +174,15 @@ void LLFloaterFixedEnvironment::refresh() } } +void LLFloaterFixedEnvironment::setEditSettingsAndUpdate(const LLSettingsBase::ptr_t &settings) +{ + mSettings = settings; // shouldn't this do buildDeepCloneAndUncompress() ? + updateEditEnvironment(); + syncronizeTabs(); + refresh(); + LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_FAST); +} + void LLFloaterFixedEnvironment::syncronizeTabs() { S32 count = mTab->getTabCount(); @@ -250,131 +213,9 @@ LLFloaterSettingsPicker * LLFloaterFixedEnvironment::getSettingsPicker() return picker; } -void LLFloaterFixedEnvironment::loadInventoryItem(const LLUUID &inventoryId, bool can_trans) -{ - if (inventoryId.isNull()) - { - mInventoryItem = nullptr; - mInventoryId.setNull(); - mCanMod = true; - mCanCopy = true; - mCanTrans = true; - return; - } - - mInventoryId = inventoryId; - LL_INFOS("SETTINGS") << "Setting edit inventory item to " << mInventoryId << "." << LL_ENDL; - mInventoryItem = gInventory.getItem(mInventoryId); - - if (!mInventoryItem) - { - LL_WARNS("SETTINGS") << "Could not find inventory item with Id = " << mInventoryId << LL_ENDL; - LLNotificationsUtil::add("CantFindInvItem"); - closeFloater(); - - mInventoryId.setNull(); - mInventoryItem = nullptr; - return; - } - - if (mInventoryItem->getAssetUUID().isNull()) - { - LL_WARNS("ENVIRONMENT") << "Asset ID in inventory item is NULL (" << mInventoryId << ")" << LL_ENDL; - LLNotificationsUtil::add("UnableEditItem"); - closeFloater(); - - mInventoryId.setNull(); - mInventoryItem = nullptr; - return; - } - - mCanCopy = mInventoryItem->getPermissions().allowCopyBy(gAgent.getID()); - mCanMod = mInventoryItem->getPermissions().allowModifyBy(gAgent.getID()); - mCanTrans = can_trans && mInventoryItem->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID()); - - LLSettingsVOBase::getSettingsAsset(mInventoryItem->getAssetUUID(), - [this](LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, LLExtStat) { onAssetLoaded(asset_id, settings, status); }); -} - - -void LLFloaterFixedEnvironment::checkAndConfirmSettingsLoss(LLFloaterFixedEnvironment::on_confirm_fn cb) -{ - if (isDirty()) - { - LLSD args(LLSDMap("TYPE", mSettings->getSettingsType()) - ("NAME", mSettings->getName())); - - // create and show confirmation textbox - LLNotificationsUtil::add("SettingsConfirmLoss", args, LLSD(), - [cb](const LLSD¬if, const LLSD&resp) - { - S32 opt = LLNotificationsUtil::getSelectedOption(notif, resp); - if (opt == 0) - cb(); - }); - } - else if (cb) - { - cb(); - } -} - void LLFloaterFixedEnvironment::onPickerCommitSetting(LLUUID item_id) { loadInventoryItem(item_id); -// mInventoryId = item_id; -// mInventoryItem = gInventory.getItem(mInventoryId); -// -// mCanCopy = mInventoryItem->getPermissions().allowCopyBy(gAgent.getID()); -// mCanMod = mInventoryItem->getPermissions().allowModifyBy(gAgent.getID()); -// mCanTrans = mInventoryItem->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID()); -// -// LLSettingsVOBase::getSettingsAsset(mInventoryItem->getAssetUUID(), -// [this](LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, LLExtStat) { onAssetLoaded(asset_id, settings, status); }); -} - -void LLFloaterFixedEnvironment::onAssetLoaded(LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status) -{ - if (mInventoryItem && mInventoryItem->getAssetUUID() != asset_id) - { - LL_WARNS("ENVIRONMENT") << "Discarding obsolete asset callback" << LL_ENDL; - return; - } - - clearDirtyFlag(); - - if (!settings || status) - { - LLSD args; - args["NAME"] = (mInventoryItem) ? mInventoryItem->getName() : asset_id.asString(); - LLNotificationsUtil::add("FailedToFindSettings", args); - closeFloater(); - return; - } - - mSettings = settings; - if (mInventoryItem) - mSettings->setName(mInventoryItem->getName()); - - if (mCanCopy) - settings->clearFlag(LLSettingsBase::FLAG_NOCOPY); - else - settings->setFlag(LLSettingsBase::FLAG_NOCOPY); - - if (mCanMod) - settings->clearFlag(LLSettingsBase::FLAG_NOMOD); - else - settings->setFlag(LLSettingsBase::FLAG_NOMOD); - - if (mCanTrans) - settings->clearFlag(LLSettingsBase::FLAG_NOTRANS); - else - settings->setFlag(LLSettingsBase::FLAG_NOTRANS); - - updateEditEnvironment(); - syncronizeTabs(); - refresh(); - LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_FAST); } void LLFloaterFixedEnvironment::onNameChanged(const std::string &name) @@ -473,51 +314,6 @@ void LLFloaterFixedEnvironment::onButtonApply(LLUICtrl *ctrl, const LLSD &data) } } -void LLFloaterFixedEnvironment::onSaveAsCommit(const LLSD& notification, const LLSD& response, const LLSettingsBase::ptr_t &settings) -{ - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - if (0 == option) - { - std::string settings_name = response["message"].asString(); - - LLInventoryObject::correctInventoryName(settings_name); - if (settings_name.empty()) - { - // Ideally notification should disable 'OK' button if name won't fit our requirements, - // for now either display notification, or use some default name - settings_name = "Unnamed"; - } - - if (mCanMod) - { - doApplyCreateNewInventory(settings_name, settings); - } - else if (mInventoryItem) - { - const LLUUID &marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false); - LLUUID parent_id = mInventoryItem->getParentUUID(); - - if ((marketplacelistings_id == parent_id) || gInventory.isObjectDescendentOf(mInventoryItem->getUUID(), gInventory.getLibraryRootFolderID())) - { - parent_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS); - } - - LLPointer cb = new LLFixedSettingCopiedCallback(getHandle()); - copy_inventory_item( - gAgent.getID(), - mInventoryItem->getPermissions().getOwner(), - mInventoryItem->getUUID(), - parent_id, - settings_name, - cb); - } - else - { - LL_WARNS() << "Failed to copy fixed env setting" << LL_ENDL; - } - } -} - void LLFloaterFixedEnvironment::onClickCloseBtn(bool app_quitting) { if (!app_quitting) @@ -531,116 +327,6 @@ void LLFloaterFixedEnvironment::onButtonLoad() checkAndConfirmSettingsLoss([this](){ doSelectFromInventory(); }); } -void LLFloaterFixedEnvironment::doApplyCreateNewInventory(std::string settings_name, const LLSettingsBase::ptr_t &settings) -{ - if (mInventoryItem) - { - LLUUID parent_id = mInventoryItem->getParentUUID(); - U32 next_owner_perm = mInventoryItem->getPermissions().getMaskNextOwner(); - LLSettingsVOBase::createInventoryItem(settings, next_owner_perm, parent_id, settings_name, - [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryCreated(asset_id, inventory_id, results); }); - } - else - { - LLUUID parent_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS); - // This method knows what sort of settings object to create. - LLSettingsVOBase::createInventoryItem(settings, parent_id, settings_name, - [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryCreated(asset_id, inventory_id, results); }); - } -} - -void LLFloaterFixedEnvironment::doApplyUpdateInventory(const LLSettingsBase::ptr_t &settings) -{ - LL_DEBUGS("ENVEDIT") << "Update inventory for " << mInventoryId << LL_ENDL; - if (mInventoryId.isNull()) - { - LLSettingsVOBase::createInventoryItem(settings, gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS), std::string(), - [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryCreated(asset_id, inventory_id, results); }); - } - else - { - LLSettingsVOBase::updateInventoryItem(settings, mInventoryId, - [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryUpdated(asset_id, inventory_id, results); }); - } -} - -void LLFloaterFixedEnvironment::doApplyEnvironment(const std::string &where, const LLSettingsBase::ptr_t &settings) -{ - U32 flags(0); - - if (mInventoryItem) - { - if (!mInventoryItem->getPermissions().allowOperationBy(PERM_MODIFY, gAgent.getID())) - flags |= LLSettingsBase::FLAG_NOMOD; - if (!mInventoryItem->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID())) - flags |= LLSettingsBase::FLAG_NOTRANS; - } - - flags |= settings->getFlags(); - settings->setFlag(flags); - - if (where == ACTION_APPLY_LOCAL) - { - settings->setName("Local"); // To distinguish and make sure there is a name. Safe, because this is a copy. - LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, settings); - } - else if (where == ACTION_APPLY_PARCEL) - { - LLParcel *parcel(LLViewerParcelMgr::instance().getAgentOrSelectedParcel()); - - if ((!parcel) || (parcel->getLocalID() == INVALID_PARCEL_ID)) - { - LL_WARNS("ENVIRONMENT") << "Can not identify parcel. Not applying." << LL_ENDL; - LLNotificationsUtil::add("WLParcelApplyFail"); - return; - } - - if (mInventoryItem && !isDirty()) - { - LLEnvironment::instance().updateParcel(parcel->getLocalID(), mInventoryItem->getAssetUUID(), mInventoryItem->getName(), LLEnvironment::NO_TRACK, -1, -1, flags); - } - else if (settings->getSettingsType() == "sky") - { - LLEnvironment::instance().updateParcel(parcel->getLocalID(), std::static_pointer_cast(settings), -1, -1); - } - else if (settings->getSettingsType() == "water") - { - LLEnvironment::instance().updateParcel(parcel->getLocalID(), std::static_pointer_cast(settings), -1, -1); - } - } - else if (where == ACTION_APPLY_REGION) - { - if (mInventoryItem && !isDirty()) - { - LLEnvironment::instance().updateRegion(mInventoryItem->getAssetUUID(), mInventoryItem->getName(), LLEnvironment::NO_TRACK, -1, -1, flags); - } - else if (settings->getSettingsType() == "sky") - { - LLEnvironment::instance().updateRegion(std::static_pointer_cast(settings), -1, -1); - } - else if (settings->getSettingsType() == "water") - { - LLEnvironment::instance().updateRegion(std::static_pointer_cast(settings), -1, -1); - } - } - else - { - LL_WARNS("ENVIRONMENT") << "Unknown apply '" << where << "'" << LL_ENDL; - return; - } - -} - -void LLFloaterFixedEnvironment::doCloseInventoryFloater(bool quitting) -{ - LLFloater* floaterp = mInventoryFloater.get(); - - if (floaterp) - { - floaterp->closeFloater(quitting); - } -} - void LLFloaterFixedEnvironment::onInventoryCreated(LLUUID asset_id, LLUUID inventory_id, LLSD results) { LL_WARNS("ENVIRONMENT") << "Inventory item " << inventory_id << " has been created with asset " << asset_id << " results are:" << results << LL_ENDL; @@ -710,28 +396,6 @@ void LLFloaterFixedEnvironment::doSelectFromInventory() picker->setFocus(TRUE); } -void LLFloaterFixedEnvironment::onPanelDirtyFlagChanged(bool value) -{ - if (value) - setDirtyFlag(); -} - -//------------------------------------------------------------------------- -bool LLFloaterFixedEnvironment::canUseInventory() const -{ - return LLEnvironment::instance().isInventoryEnabled(); -} - -bool LLFloaterFixedEnvironment::canApplyRegion() const -{ - return gAgent.canManageEstate(); -} - -bool LLFloaterFixedEnvironment::canApplyParcel() const -{ - return LLEnvironment::instance().canAgentUpdateParcelEnvironment(); -} - //========================================================================= LLFloaterFixedEnvironmentWater::LLFloaterFixedEnvironmentWater(const LLSD &key): LLFloaterFixedEnvironment(key) diff --git a/indra/newview/llfloaterfixedenvironment.h b/indra/newview/llfloaterfixedenvironment.h index 513996c4a3..f35f4a4368 100644 --- a/indra/newview/llfloaterfixedenvironment.h +++ b/indra/newview/llfloaterfixedenvironment.h @@ -27,7 +27,7 @@ #ifndef LL_FLOATERFIXEDENVIRONMENT_H #define LL_FLOATERFIXEDENVIRONMENT_H -#include "llfloater.h" +#include "llfloatereditenvironmentbase.h" #include "llsettingsbase.h" #include "llflyoutcombobtn.h" #include "llinventory.h" @@ -43,15 +43,10 @@ class LLFixedSettingCopiedCallback; /** * Floater container for creating and editing fixed environment settings. */ -class LLFloaterFixedEnvironment : public LLFloater +class LLFloaterFixedEnvironment : public LLFloaterEditEnvironmentBase { LOG_CLASS(LLFloaterFixedEnvironment); - - friend class LLFixedSettingCopiedCallback; - public: - static const std::string KEY_INVENTORY_ID; - LLFloaterFixedEnvironment(const LLSD &key); ~LLFloaterFixedEnvironment(); @@ -59,64 +54,35 @@ public: virtual void onOpen(const LLSD& key) override; virtual void onClose(bool app_quitting) override; - virtual void onFocusReceived() override; - virtual void onFocusLost() override; - void setEditSettings(const LLSettingsBase::ptr_t &settings) { mSettings = settings; clearDirtyFlag(); syncronizeTabs(); refresh(); } - LLSettingsBase::ptr_t getEditSettings() const { return mSettings; } - - virtual BOOL isDirty() const override { return getIsDirty(); } + virtual LLSettingsBase::ptr_t getEditSettings() const override { return mSettings; } protected: typedef std::function on_confirm_fn; - virtual void updateEditEnvironment() = 0; virtual void refresh() override; + void setEditSettingsAndUpdate(const LLSettingsBase::ptr_t &settings) override; virtual void syncronizeTabs(); - LLFloaterSettingsPicker *getSettingsPicker(); - - void loadInventoryItem(const LLUUID &inventoryId, bool can_trans = true); - - void checkAndConfirmSettingsLoss(on_confirm_fn cb); + virtual LLFloaterSettingsPicker *getSettingsPicker() override; LLTabContainer * mTab; LLLineEditor * mTxtName; LLSettingsBase::ptr_t mSettings; - virtual void doImportFromDisk() = 0; - virtual void doApplyCreateNewInventory(std::string settings_name, const LLSettingsBase::ptr_t &settings); - virtual void doApplyUpdateInventory(const LLSettingsBase::ptr_t &settings); - virtual void doApplyEnvironment(const std::string &where, const LLSettingsBase::ptr_t &settings); - void doCloseInventoryFloater(bool quitting = false); - - bool canUseInventory() const; - bool canApplyRegion() const; - bool canApplyParcel() const; - LLFlyoutComboBtnCtrl * mFlyoutControl; - LLUUID mInventoryId; - LLInventoryItem * mInventoryItem; - LLHandle mInventoryFloater; - bool mCanCopy; - bool mCanMod; - bool mCanTrans; - void onInventoryCreated(LLUUID asset_id, LLUUID inventory_id); void onInventoryCreated(LLUUID asset_id, LLUUID inventory_id, LLSD results); void onInventoryUpdated(LLUUID asset_id, LLUUID inventory_id, LLSD results); - bool getIsDirty() const { return mIsDirty; } - void setDirtyFlag() { mIsDirty = true; } - virtual void clearDirtyFlag(); + virtual void clearDirtyFlag() override; + void updatePermissionFlags(); void doSelectFromInventory(); - void onPanelDirtyFlagChanged(bool); virtual void onClickCloseBtn(bool app_quitting = false) override; - void onSaveAsCommit(const LLSD& notification, const LLSD& response, const LLSettingsBase::ptr_t &settings); private: void onNameChanged(const std::string &name); @@ -126,9 +92,6 @@ private: void onButtonLoad(); void onPickerCommitSetting(LLUUID item_id); - void onAssetLoaded(LLUUID asset_id, LLSettingsBase::ptr_t settins, S32 status); - - bool mIsDirty; }; class LLFloaterFixedEnvironmentWater : public LLFloaterFixedEnvironment @@ -172,36 +135,4 @@ protected: private: }; -class LLSettingsEditPanel : public LLPanel -{ -public: - virtual void setSettings(const LLSettingsBase::ptr_t &) = 0; - - typedef boost::signals2::signal on_dirty_charged_sg; - typedef boost::signals2::connection connection_t; - - inline bool getIsDirty() const { return mIsDirty; } - inline void setIsDirty() { mIsDirty = true; if (!mOnDirtyChanged.empty()) mOnDirtyChanged(this, mIsDirty); } - inline void clearIsDirty() { mIsDirty = false; if (!mOnDirtyChanged.empty()) mOnDirtyChanged(this, mIsDirty); } - - inline bool getCanChangeSettings() const { return mCanEdit; } - inline void setCanChangeSettings(bool flag) { mCanEdit = flag; } - - inline connection_t setOnDirtyFlagChanged(on_dirty_charged_sg::slot_type cb) { return mOnDirtyChanged.connect(cb); } - - -protected: - LLSettingsEditPanel() : - LLPanel(), - mIsDirty(false), - mOnDirtyChanged() - {} - -private: - bool mIsDirty; - bool mCanEdit; - - on_dirty_charged_sg mOnDirtyChanged; -}; - #endif // LL_FLOATERFIXEDENVIRONMENT_H diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp index 59d5f72146..5395f517a3 100644 --- a/indra/newview/llfloaterimcontainer.cpp +++ b/indra/newview/llfloaterimcontainer.cpp @@ -313,12 +313,15 @@ void LLFloaterIMContainer::addFloater(LLFloater* floaterp, LLIconCtrl* icon = 0; + bool is_in_group = gAgent.isInGroup(session_id, TRUE); + LLUUID icon_id; - if(gAgent.isInGroup(session_id, TRUE)) + if (is_in_group) { LLGroupIconCtrl::Params icon_params; icon_params.group_id = session_id; icon = LLUICtrlFactory::instance().create(icon_params); + icon_id = session_id; mSessions[session_id] = floaterp; floaterp->mCloseSignal.connect(boost::bind(&LLFloaterIMContainer::onCloseFloater, this, session_id)); @@ -330,11 +333,18 @@ void LLFloaterIMContainer::addFloater(LLFloater* floaterp, LLAvatarIconCtrl::Params icon_params; icon_params.avatar_id = avatar_id; icon = LLUICtrlFactory::instance().create(icon_params); + icon_id = avatar_id; mSessions[session_id] = floaterp; floaterp->mCloseSignal.connect(boost::bind(&LLFloaterIMContainer::onCloseFloater, this, session_id)); } + LLFloaterIMSessionTab* floater = LLFloaterIMSessionTab::getConversation(session_id); + if (floater) + { + floater->updateChatIcon(icon_id); + } + // forced resize of the floater LLRect wrapper_rect = this->mTabContainer->getLocalRect(); floaterp->setRect(wrapper_rect); @@ -1829,6 +1839,8 @@ bool LLFloaterIMContainer::removeConversationListItem(const LLUUID& uuid, bool c { new_selection = mConversationsRoot->getPreviousFromChild(widget, FALSE); } + + // Will destroy views and delete models that are not assigned to any views widget->destroyView(); } diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp index ba5679fa7c..065d41d019 100644 --- a/indra/newview/llfloaterimsessiontab.cpp +++ b/indra/newview/llfloaterimsessiontab.cpp @@ -34,6 +34,8 @@ #include "llagent.h" #include "llagentcamera.h" #include "llavataractions.h" +#include "llavatariconctrl.h" +#include "llgroupiconctrl.h" #include "llchatentry.h" #include "llchathistory.h" #include "llchiclet.h" @@ -47,6 +49,9 @@ #include "llfloaterimnearbychat.h" const F32 REFRESH_INTERVAL = 1.0f; +const std::string ICN_GROUP("group_chat_icon"); +const std::string ICN_NEARBY("nearby_chat_icon"); +const std::string ICN_AVATAR("avatar_icon"); void cb_group_do_nothing() { @@ -531,8 +536,7 @@ void LLFloaterIMSessionTab::removeConversationViewParticipant(const LLUUID& part LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,participant_id); if (widget) { - mConversationsRoot->extractItem(widget); - delete widget; + widget->destroyView(); } mConversationsWidgets.erase(participant_id); } @@ -702,6 +706,39 @@ void LLFloaterIMSessionTab::updateSessionName(const std::string& name) mInputEditor->setLabel(LLTrans::getString("IM_to_label") + " " + name); } +void LLFloaterIMSessionTab::updateChatIcon(const LLUUID& id) +{ + if (mSession) + { + if (mSession->isP2PSessionType()) + { + LLAvatarIconCtrl* icon = getChild(ICN_AVATAR); + icon->setVisible(true); + icon->setValue(id); + } + if (mSession->isAdHocSessionType()) + { + LLGroupIconCtrl* icon = getChild(ICN_GROUP); + icon->setVisible(true); + } + if (mSession->isGroupSessionType()) + { + LLGroupIconCtrl* icon = getChild(ICN_GROUP); + icon->setVisible(true); + icon->setValue(id); + } + } + else + { + if (mIsNearbyChat) + { + LLIconCtrl* icon = getChild(ICN_NEARBY); + icon->setVisible(true); + } + } + +} + void LLFloaterIMSessionTab::hideAllStandardButtons() { for (S32 i = 0; i < BUTTON_COUNT; i++) diff --git a/indra/newview/llfloaterimsessiontab.h b/indra/newview/llfloaterimsessiontab.h index 112c281639..ef15c4386f 100644 --- a/indra/newview/llfloaterimsessiontab.h +++ b/indra/newview/llfloaterimsessiontab.h @@ -105,6 +105,8 @@ public: void restoreFloater(); void saveCollapsedState(); + void updateChatIcon(const LLUUID& id); + LLView* getChatHistory(); protected: diff --git a/indra/newview/llfloatermarketplacelistings.cpp b/indra/newview/llfloatermarketplacelistings.cpp index 49bb439a24..2bfd4dda3c 100644 --- a/indra/newview/llfloatermarketplacelistings.cpp +++ b/indra/newview/llfloatermarketplacelistings.cpp @@ -104,14 +104,17 @@ void LLPanelMarketplaceListings::buildAllPanels() panel = buildInventoryPanel("Active Items", "panel_marketplace_listings_listed.xml"); panel->getFilter().setFilterMarketplaceActiveFolders(); panel->getFilter().setEmptyLookupMessage("MarketplaceNoMatchingItems"); + panel->getFilter().setDefaultEmptyLookupMessage("MarketplaceNoListing"); panel->getFilter().markDefault(); panel = buildInventoryPanel("Inactive Items", "panel_marketplace_listings_unlisted.xml"); panel->getFilter().setFilterMarketplaceInactiveFolders(); panel->getFilter().setEmptyLookupMessage("MarketplaceNoMatchingItems"); + panel->getFilter().setDefaultEmptyLookupMessage("MarketplaceNoListing"); panel->getFilter().markDefault(); panel = buildInventoryPanel("Unassociated Items", "panel_marketplace_listings_unassociated.xml"); panel->getFilter().setFilterMarketplaceUnassociatedFolders(); panel->getFilter().setEmptyLookupMessage("MarketplaceNoMatchingItems"); + panel->getFilter().setDefaultEmptyLookupMessage("MarketplaceNoListing"); panel->getFilter().markDefault(); // Set the tab panel diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index 213513c8a2..f24c047c25 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -105,6 +105,11 @@ LLMeshFilePicker::LLMeshFilePicker(LLModelPreview* mp, S32 lod) void LLMeshFilePicker::notify(const std::vector& filenames) { + if(LLAppViewer::instance()->quitRequested()) + { + return; + } + if (filenames.size() > 0) { mMP->loadModel(filenames[0], mLOD); diff --git a/indra/newview/llgroupactions.cpp b/indra/newview/llgroupactions.cpp index 2fa1a3aaf8..0aaed1d611 100644 --- a/indra/newview/llgroupactions.cpp +++ b/indra/newview/llgroupactions.cpp @@ -39,6 +39,7 @@ #include "llfloaterimcontainer.h" #include "llimview.h" // for gIMMgr #include "llnotificationsutil.h" +#include "llstartup.h" #include "llstatusbar.h" // can_afford_transaction() #include "groupchatlistener.h" // [RLVa:KB] - Checked: 2011-03-28 (RLVa-1.3.0) @@ -71,6 +72,11 @@ public: bool handle(const LLSD& tokens, const LLSD& query_map, LLMediaCtrl* web) { + if (LLStartUp::getStartupState() < STATE_STARTED) + { + return true; + } + if (!LLUI::getInstance()->mSettingGroups["config"]->getBOOL("EnableGroupInfo")) { LLNotificationsUtil::add("NoGroupInfo", LLSD(), LLSD(), std::string("SwitchToStandardSkinAndQuit")); diff --git a/indra/newview/llimprocessing.cpp b/indra/newview/llimprocessing.cpp index 1fb4b77094..df2c2dbcbd 100644 --- a/indra/newview/llimprocessing.cpp +++ b/indra/newview/llimprocessing.cpp @@ -1280,7 +1280,19 @@ void LLIMProcessing::processNewMessage(LLUUID from_id, // group is not blocked, but we still need to check agent that sent the invitation // and we have no agent's id // Note: server sends username "first.last". - is_muted |= LLMuteList::getInstance()->isMuted(name); + // Fix broken mute check for avatars without last name: + // Names without last names are stored with capital first letter + // in the mute list, but they arrive here completely in lower case. + // So we need to change the first letter to upper case in order to + // make the mute check actually work. + //is_muted |= LLMuteList::getInstance()->isMuted(name); + std::string check_name(name); + if (!check_name.empty() && check_name.find('.') == std::string::npos) + { + check_name[0] = toupper(check_name[0]); + } + is_muted |= LLMuteList::getInstance()->isMuted(check_name); + // } if (is_do_not_disturb || is_muted) { diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index c1ac3e755d..2a09211517 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -1131,6 +1131,9 @@ void LLIMModel::LLIMSession::buildHistoryFileName() } // [Legacy IM logfile names] } + + // user's account name can change, but filenames and session names are account name based + LLConversationLog::getInstance()->verifyFilename(mSessionID, mHistoryFileName, av_name.getCompleteName()); } else if (isGroupChat()) { diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp index ded58caba3..e84fbeb577 100644 --- a/indra/newview/llinventoryfilter.cpp +++ b/indra/newview/llinventoryfilter.cpp @@ -80,6 +80,7 @@ LLInventoryFilter::LLInventoryFilter(const Params& p) : mName(p.name), mFilterModified(FILTER_NONE), mEmptyLookupMessage("InventoryNoMatchingItems"), + mDefaultEmptyLookupMessage(""), mFilterOps(p.filter_ops), mBackupFilterOps(mFilterOps), mFilterSubString(p.substring), @@ -1604,12 +1605,24 @@ void LLInventoryFilter::setEmptyLookupMessage(const std::string& message) mEmptyLookupMessage = message; } +void LLInventoryFilter::setDefaultEmptyLookupMessage(const std::string& message) +{ + mDefaultEmptyLookupMessage = message; +} + std::string LLInventoryFilter::getEmptyLookupMessage() const { - LLStringUtil::format_map_t args; - args["[SEARCH_TERM]"] = LLURI::escape(getFilterSubStringOrig()); + if (isDefault() && !mDefaultEmptyLookupMessage.empty()) + { + return LLTrans::getString(mDefaultEmptyLookupMessage); + } + else + { + LLStringUtil::format_map_t args; + args["[SEARCH_TERM]"] = LLURI::escape(getFilterSubStringOrig()); - return LLTrans::getString(mEmptyLookupMessage, args); + return LLTrans::getString(mEmptyLookupMessage, args); + } } diff --git a/indra/newview/llinventoryfilter.h b/indra/newview/llinventoryfilter.h index f726c1efc0..d2ebda7149 100644 --- a/indra/newview/llinventoryfilter.h +++ b/indra/newview/llinventoryfilter.h @@ -270,6 +270,7 @@ public: EFilterCreatorType getFilterCreatorType() const; void setEmptyLookupMessage(const std::string& message); + void setDefaultEmptyLookupMessage(const std::string& message); std::string getEmptyLookupMessage() const; // +-------------------------------------------------------------------+ @@ -346,6 +347,7 @@ private: std::string mFilterText; std::string mEmptyLookupMessage; + std::string mDefaultEmptyLookupMessage; ESearchType mSearchType; diff --git a/indra/newview/lllandmarklist.cpp b/indra/newview/lllandmarklist.cpp index 71c74f88db..a8c2c3ccfc 100644 --- a/indra/newview/lllandmarklist.cpp +++ b/indra/newview/lllandmarklist.cpp @@ -106,14 +106,14 @@ LLLandmark* LLLandmarkList::getAsset(const LLUUID& asset_uuid, loaded_callback_t mWaitList.insert(asset_uuid); return NULL; } - // fIRE-14457 Fix CopySLURL fails / landmakrs not loading - based on snippet from Chorazin Allen - mRequestedList[asset_uuid] = gFrameTimeSeconds; + + mRequestedList[asset_uuid] = gFrameTimeSeconds; + + // Note that getAssetData can callback immediately and cleans mRequestedList gAssetStorage->getAssetData(asset_uuid, LLAssetType::AT_LANDMARK, LLLandmarkList::processGetAssetReply, NULL); - // fIRE-14457 Fix CopySLURL fails / landmakrs not loading - based on snippet from Chorazin Allen - // mRequestedList[asset_uuid] = gFrameTimeSeconds; } return NULL; } @@ -197,11 +197,15 @@ void LLLandmarkList::processGetAssetReply( landmark_uuid_list_t::iterator iter = gLandmarkList.mWaitList.begin(); LLUUID asset_uuid = *iter; gLandmarkList.mWaitList.erase(iter); + + // add to mRequestedList before calling getAssetData() + gLandmarkList.mRequestedList[asset_uuid] = gFrameTimeSeconds; + + // Note that getAssetData can callback immediately and cleans mRequestedList gAssetStorage->getAssetData(asset_uuid, LLAssetType::AT_LANDMARK, LLLandmarkList::processGetAssetReply, NULL); - gLandmarkList.mRequestedList[asset_uuid] = gFrameTimeSeconds; } scheduling = false; } diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp index 3a8397fa37..2738b4c0d5 100644 --- a/indra/newview/lllogchat.cpp +++ b/indra/newview/lllogchat.cpp @@ -352,6 +352,28 @@ std::string LLLogChat::makeLogFileName(std::string filename) return filename; } +//static +void LLLogChat::renameLogFile(const std::string& old_filename, const std::string& new_filename) +{ + std::string new_name = cleanFileName(new_filename); + std::string old_name = cleanFileName(old_filename); + new_name = gDirUtilp->getExpandedFilename(LL_PATH_PER_ACCOUNT_CHAT_LOGS, new_name); + old_name = gDirUtilp->getExpandedFilename(LL_PATH_PER_ACCOUNT_CHAT_LOGS, old_name); + + if (new_name.empty() || old_name.empty()) + { + return; + } + + new_name += '.' + LL_TRANSCRIPT_FILE_EXTENSION; + old_name += '.' + LL_TRANSCRIPT_FILE_EXTENSION; + + if (!LLFile::isfile(new_name) && LLFile::isfile(old_name)) + { + LLFile::rename(old_name, new_name); + } +} + std::string LLLogChat::cleanFileName(std::string filename) { std::string invalidChars = "\"\'\\/?*:.<>|[]{}~"; // Cannot match glob or illegal filename chars diff --git a/indra/newview/lllogchat.h b/indra/newview/lllogchat.h index f6a186ae98..a0c7fbac6c 100644 --- a/indra/newview/lllogchat.h +++ b/indra/newview/lllogchat.h @@ -94,6 +94,7 @@ public: static std::string timestamp(bool withdate = false); static std::string makeLogFileName(std::string(filename)); + static void renameLogFile(const std::string& old_filename, const std::string& new_filename); /** *Add functions to get old and non date stamped file names when needed */ diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp index 70c80e3315..ba175c27ca 100644 --- a/indra/newview/lllogininstance.cpp +++ b/indra/newview/lllogininstance.cpp @@ -58,6 +58,7 @@ #include "llevents.h" #include "llappviewer.h" #include "llsdserialize.h" +#include "lltrans.h" #include #include @@ -347,7 +348,7 @@ void LLLoginInstance::handleLoginFailure(const LLSD& event) { data["certificate"] = response["certificate"]; } - + if (gViewerWindow) gViewerWindow->setShowProgress(FALSE, FALSE); LLFloaterReg::showInstance("message_critical", data); @@ -363,13 +364,36 @@ void LLLoginInstance::handleLoginFailure(const LLSD& event) // login.cgi is insisting on a required update. We were called with an // event that bundles both the login.cgi 'response' and the // synchronization event from the 'updater'. - std::string required_version = response["message_args"]["VERSION"]; - LL_WARNS("LLLogin") << "Login failed because an update to version " << required_version << " is required." << LL_ENDL; + std::string login_version = response["message_args"]["VERSION"]; + std::string vvm_version = updater["VERSION"]; + std::string relnotes = updater["URL"]; + LL_WARNS("LLLogin") << "Login failed because an update to version " << login_version << " is required." << LL_ENDL; + // vvm_version might be empty because we might not have gotten + // SLVersionChecker's LoginSync handshake. But if it IS populated, it + // should (!) be the same as the version we got from login.cgi. + if ((! vvm_version.empty()) && vvm_version != login_version) + { + LL_WARNS("LLLogin") << "VVM update version " << vvm_version + << " differs from login version " << login_version + << "; presenting VVM version to match release notes URL" + << LL_ENDL; + login_version = vvm_version; + } + if (relnotes.empty() || relnotes.find("://") == std::string::npos) + { + relnotes = LLTrans::getString("RELEASE_NOTES_BASE_URL"); + if (!LLStringUtil::endsWith(relnotes, "/")) + relnotes += "/"; + relnotes += LLURI::escape(login_version) + ".html"; + } if (gViewerWindow) gViewerWindow->setShowProgress(FALSE, FALSE); - LLSD args(LLSDMap("VERSION", required_version)); + LLSD args; + args["VERSION"] = login_version; + args["URL"] = relnotes; + if (updater.isUndefined()) { // If the updater failed to shake hands, better advise the user to diff --git a/indra/newview/llnotificationhandler.h b/indra/newview/llnotificationhandler.h index ea97456528..7be8c5d0cb 100644 --- a/indra/newview/llnotificationhandler.h +++ b/indra/newview/llnotificationhandler.h @@ -302,6 +302,7 @@ public: * Writes notification message to IM p2p session. */ static void logToIMP2P(const LLNotificationPtr& notification, bool to_file_only = false); + static void logToIMP2P(const LLUUID& from_id, const std::string& message, bool to_file_only = false); /** * Writes group notice notification message to IM group session. diff --git a/indra/newview/llnotificationhandlerutil.cpp b/indra/newview/llnotificationhandlerutil.cpp index 3666ef7bc4..265fe6af48 100644 --- a/indra/newview/llnotificationhandlerutil.cpp +++ b/indra/newview/llnotificationhandlerutil.cpp @@ -174,15 +174,13 @@ void log_name_callback(const LLAvatarName& av_name, const std::string& from_name } // static -void LLHandlerUtil::logToIMP2P(const LLNotificationPtr& notification, bool to_file_only) +void LLHandlerUtil::logToIMP2P(const LLUUID& from_id, const std::string& message, bool to_file_only) { if (!gCacheName) { return; } - LLUUID from_id = notification->getPayload()["from_id"]; - if (from_id.isNull()) { // Normal behavior for system generated messages, don't spam. @@ -192,14 +190,21 @@ void LLHandlerUtil::logToIMP2P(const LLNotificationPtr& notification, bool to_fi if(to_file_only) { - LLAvatarNameCache::get(from_id, boost::bind(&log_name_callback, _2, "", notification->getMessage(), LLUUID())); + LLAvatarNameCache::get(from_id, boost::bind(&log_name_callback, _2, "", message, LLUUID())); } else { - LLAvatarNameCache::get(from_id, boost::bind(&log_name_callback, _2, INTERACTIVE_SYSTEM_FROM, notification->getMessage(), from_id)); + LLAvatarNameCache::get(from_id, boost::bind(&log_name_callback, _2, INTERACTIVE_SYSTEM_FROM, message, from_id)); } } +// static +void LLHandlerUtil::logToIMP2P(const LLNotificationPtr& notification, bool to_file_only) +{ + LLUUID from_id = notification->getPayload()["from_id"]; + logToIMP2P(from_id, notification->getMessage(), to_file_only); +} + // static void LLHandlerUtil::logGroupNoticeToIMGroup( const LLNotificationPtr& notification) diff --git a/indra/newview/llnotificationofferhandler.cpp b/indra/newview/llnotificationofferhandler.cpp index 58cf7cc624..faa0cf2e23 100644 --- a/indra/newview/llnotificationofferhandler.cpp +++ b/indra/newview/llnotificationofferhandler.cpp @@ -40,6 +40,8 @@ #include "rlvactions.h" // [/RLVa:KB] +#include + using namespace LLNotificationsUI; //-------------------------------------------------------------------------- @@ -167,7 +169,19 @@ bool LLOfferHandler::processNotification(const LLNotificationPtr& notification) { // log only to file if notif panel can be embedded to IM and IM is opened bool file_only = add_notif_to_im && LLHandlerUtil::isIMFloaterOpened(notification); - LLHandlerUtil::logToIMP2P(notification, file_only); + if ((notification->getName() == "TeleportOffered" + || notification->getName() == "TeleportOffered_MaturityExceeded" + || notification->getName() == "TeleportOffered_MaturityBlocked")) + { + boost::regex r("\\s*([^<]*)?\\s*( - )?", + boost::regex::perl|boost::regex::icase); + std::string stripped_msg = boost::regex_replace(notification->getMessage(), r, ""); + LLHandlerUtil::logToIMP2P(notification->getPayload()["from_id"], stripped_msg,file_only); + } + else + { + LLHandlerUtil::logToIMP2P(notification, file_only); + } } } diff --git a/indra/newview/llpaneleditsky.h b/indra/newview/llpaneleditsky.h index c02c9c95a0..801fb8b9b2 100644 --- a/indra/newview/llpaneleditsky.h +++ b/indra/newview/llpaneleditsky.h @@ -29,7 +29,7 @@ #include "llpanel.h" #include "llsettingssky.h" -#include "llfloaterfixedenvironment.h" +#include "llfloatereditenvironmentbase.h" //========================================================================= class LLSlider; diff --git a/indra/newview/llpaneleditwater.h b/indra/newview/llpaneleditwater.h index ab2dc47bcc..4b7ec903c9 100644 --- a/indra/newview/llpaneleditwater.h +++ b/indra/newview/llpaneleditwater.h @@ -30,7 +30,7 @@ #include "llpanel.h" #include "llsettingswater.h" -#include "llfloaterfixedenvironment.h" +#include "llfloatereditenvironmentbase.h" //========================================================================= class LLSlider; diff --git a/indra/newview/llpanellandaudio.cpp b/indra/newview/llpanellandaudio.cpp index a6f320c964..012839660c 100644 --- a/indra/newview/llpanellandaudio.cpp +++ b/indra/newview/llpanellandaudio.cpp @@ -169,12 +169,9 @@ void LLPanelLandAudio::refresh() std::string current_url = parcel->getMusicURL(); mMusicURLEdit->clearRows(); LLSD streamlist = gSavedSettings.getLLSD("FSStreamList"); - // FIRE-29157 - Remove invalid URLs that were rejected by the server - //LLSD streams = streamlist["audio"]; LLSD& streams = streamlist["audio"]; - // - for(LLSD::array_iterator s_itr = streams.beginArray(); s_itr != streams.endArray(); ++s_itr) + for (LLSD::array_iterator s_itr = streams.beginArray(); s_itr != streams.endArray(); ++s_itr) { mMusicURLEdit->add(LLSD(*s_itr)); LL_DEBUGS() << "adding: " << *s_itr << " to the audio stream combo." << LL_ENDL; @@ -198,6 +195,7 @@ void LLPanelLandAudio::refresh() { if ((*iter).asString() == mLastSetURL) { + LL_WARNS() << "Removing stream from saved streams list because it was rejected by the region: " << mLastSetURL << LL_ENDL; streams.erase(index); break; } @@ -298,6 +296,10 @@ void LLPanelLandAudio::onBtnStreamAdd() gSavedSettings.setLLSD("FSStreamList", streamlist); refresh(); } + else + { + LL_INFOS() << "Could not add stream to saved streams list because it is already in the list: " << music_url << LL_ENDL; + } } } @@ -305,14 +307,12 @@ void LLPanelLandAudio::onBtnStreamDelete() { std::string music_url = mMusicURLEdit->getSimple(); LLStringUtil::trim(music_url); - // FIRE-29157 - Stream can't be deleted if onCommitAny() prepended "http://" to the URL since it doesn't match in the list. std::string music_url_no_http; if (music_url.find("http://") == 0) { music_url_no_http = music_url.substr(7, music_url.size() - 7); } - // - + LLSD streamlist = gSavedSettings.getLLSD("FSStreamList"); LLSD streamlist_new; streamlist_new["version"] = 1; @@ -320,13 +320,15 @@ void LLPanelLandAudio::onBtnStreamDelete() for (LLSD::array_const_iterator it = streamlist["audio"].beginArray(); it != streamlist["audio"].endArray(); ++it) { std::string current_url = (*it).asString(); - // FIRE-29157 - Stream can't be deleted if onCommitAny() prepended "http://" to the URL since it doesn't match in the list. - //if (current_url != music_url) if (current_url != music_url && !(current_url.find("://") == std::string::npos && current_url == music_url_no_http)) { streamlist_new["audio"].append(current_url); } - // + } + + if (streamlist["audio"].size() == streamlist_new["audio"].size()) + { + LL_WARNS() << "Could not remove stream from saved streams list: " << music_url << LL_ENDL; } gSavedSettings.setLLSD("FSStreamList", streamlist_new); diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp index 7a304ffc78..54c137d5a6 100644 --- a/indra/newview/llpanellogin.cpp +++ b/indra/newview/llpanellogin.cpp @@ -546,6 +546,16 @@ void LLPanelLogin::show(const LLRect &rect, gFocusMgr.setDefaultKeyboardFocus(sInstance); } +//static +void LLPanelLogin::reshapePanel() +{ + if (sInstance) + { + LLRect rect = sInstance->getRect(); + sInstance->reshape(rect.getWidth(), rect.getHeight()); + } +} + //static void LLPanelLogin::populateFields(LLPointer credential, bool remember_user, bool remember_psswrd) { diff --git a/indra/newview/llpanellogin.h b/indra/newview/llpanellogin.h index 963e9a3996..9e2a69317e 100644 --- a/indra/newview/llpanellogin.h +++ b/indra/newview/llpanellogin.h @@ -56,6 +56,7 @@ public: static void show(const LLRect &rect, void (*callback)(S32 option, void* user_data), void* callback_data); + static void reshapePanel(); static void populateFields(LLPointer credential, bool remember_user, bool remember_psswrd); static void resetFields(); diff --git a/indra/newview/llpanelpicks.cpp b/indra/newview/llpanelpicks.cpp index 56af092330..3470c0c7e7 100644 --- a/indra/newview/llpanelpicks.cpp +++ b/indra/newview/llpanelpicks.cpp @@ -37,6 +37,7 @@ #include "llfloatersidepanelcontainer.h" #include "llfloaterworldmap.h" #include "llnotificationsutil.h" +#include "llstartup.h" #include "lltexturectrl.h" #include "lltoggleablemenu.h" #include "lltrans.h" @@ -86,6 +87,11 @@ public: bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web) { + if (LLStartUp::getStartupState() < STATE_STARTED) + { + return true; + } + if (!LLUI::getInstance()->mSettingGroups["config"]->getBOOL("EnablePicks")) { LLNotificationsUtil::add("NoPicks", LLSD(), LLSD(), std::string("SwitchToStandardSkinAndQuit")); @@ -208,6 +214,11 @@ public: bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web) { + if (LLStartUp::getStartupState() < STATE_STARTED) + { + return true; + } + if (!LLUI::getInstance()->mSettingGroups["config"]->getBOOL("EnableClassifieds")) { LLNotificationsUtil::add("NoClassifieds", LLSD(), LLSD(), std::string("SwitchToStandardSkinAndQuit")); diff --git a/indra/newview/llpanelprimmediacontrols.cpp b/indra/newview/llpanelprimmediacontrols.cpp index e22c7df5f7..4e15de0015 100644 --- a/indra/newview/llpanelprimmediacontrols.cpp +++ b/indra/newview/llpanelprimmediacontrols.cpp @@ -74,6 +74,8 @@ const LLPanelPrimMediaControls::EZoomLevel LLPanelPrimMediaControls::kZoomLevels const int LLPanelPrimMediaControls::kNumZoomLevels = 2; const F32 EXCEEDING_ZOOM_DISTANCE = 0.5f; +const S32 ADDR_LEFT_PAD = 3; + // // LLPanelPrimMediaControls // @@ -156,7 +158,7 @@ BOOL LLPanelPrimMediaControls::postBuild() mMediaProgressPanel = getChild("media_progress_indicator"); mMediaProgressBar = getChild("media_progress_bar"); mMediaAddressCtrl = getChild("media_address"); - mMediaAddress = getChild("media_address_url"); + mMediaAddress = getChild("media_address_url"); mMediaPlaySliderPanel = getChild("media_play_position"); mMediaPlaySliderCtrl = getChild("media_play_slider"); mSkipFwdCtrl = getChild("skip_forward"); @@ -501,8 +503,10 @@ void LLPanelPrimMediaControls::updateShape() std::string test_prefix = mCurrentURL.substr(0, prefix.length()); LLStringUtil::toLower(test_prefix); mSecureURL = has_focus && (test_prefix == prefix); - mCurrentURL = (mSecureURL ? " " + mCurrentURL : mCurrentURL); - + + S32 left_pad = mSecureURL ? mSecureLockIcon->getRect().getWidth() : ADDR_LEFT_PAD; + mMediaAddress->setTextPadding(left_pad, 0); + if(mCurrentURL!=mPreviousURL) { setCurrentURL(); diff --git a/indra/newview/llpanelprimmediacontrols.h b/indra/newview/llpanelprimmediacontrols.h index 86fc036553..dd0e4ff095 100644 --- a/indra/newview/llpanelprimmediacontrols.h +++ b/indra/newview/llpanelprimmediacontrols.h @@ -39,6 +39,7 @@ class LLProgressBar; class LLSliderCtrl; class LLViewerMediaImpl; class LLWindowShade; +class LLLineEditor; class LLPanelPrimMediaControls : public LLPanel { @@ -164,7 +165,7 @@ private: LLPanel *mMediaProgressPanel; LLProgressBar *mMediaProgressBar; LLUICtrl *mMediaAddressCtrl; - LLUICtrl *mMediaAddress; + LLLineEditor *mMediaAddress; LLUICtrl *mMediaPlaySliderPanel; LLUICtrl *mMediaPlaySliderCtrl; LLUICtrl *mVolumeCtrl; diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp index 1455a2d89a..8e850c5a27 100644 --- a/indra/newview/llparticipantlist.cpp +++ b/indra/newview/llparticipantlist.cpp @@ -266,11 +266,7 @@ LLParticipantList::~LLParticipantList() */ void LLParticipantList::onAvalineCallerFound(const LLUUID& participant_id) { - LLConversationItemParticipant* participant = findParticipant(participant_id); - if (participant) - { - removeParticipant(participant); - } + removeParticipant(participant_id); // re-add avaline caller with a correct class instance. addAvatarIDExceptAgent(participant_id); } @@ -404,6 +400,7 @@ void LLParticipantList::addAvatarIDExceptAgent(const LLUUID& avatar_id) // Hack for this: LLAvatarTracker::instance().isBuddyOnline(avatar_id)) // Add the participant model to the session's children list + // This will post "add_participant" event addParticipant(participant); adjustParticipant(avatar_id); diff --git a/indra/newview/llpreviewanim.cpp b/indra/newview/llpreviewanim.cpp index 12ac9e6fc5..29accdb074 100644 --- a/indra/newview/llpreviewanim.cpp +++ b/indra/newview/llpreviewanim.cpp @@ -35,14 +35,17 @@ #include "llkeyframemotion.h" #include "llfilepicker.h" #include "lllineeditor.h" +#include "lltrans.h" #include "lluictrlfactory.h" #include "lluictrlfactory.h" #include "lldatapacker.h" extern LLAgent gAgent; +//const S32 ADVANCED_VPAD = 3; // Improved animation preview LLPreviewAnim::LLPreviewAnim(const LLSD& key) - : LLPreview( key ) + : LLPreview( key ), + pMotion(NULL) { mCommitCallbackRegistrar.add("PreviewAnim.Play", boost::bind(&LLPreviewAnim::play, this, _2)); } @@ -53,12 +56,32 @@ BOOL LLPreviewAnim::postBuild() const LLInventoryItem* item = getItem(); if(item) { - gAgentAvatarp->createMotion(item->getAssetUUID()); // preload the animation + pMotion = gAgentAvatarp->createMotion(item->getAssetUUID()); // preload the animation getChild("desc")->setValue(item->getDescription()); } childSetCommitCallback("desc", LLPreview::onText, this); getChild("desc")->setPrevalidate(&LLTextValidate::validateASCIIPrintableNoPipe); + // Improved animation preview + //getChild("adv_trigger")->setClickedCallback(boost::bind(&LLPreviewAnim::showAdvanced, this)); + //pAdvancedStatsTextBox = getChild("AdvancedStats"); + + //// Assume that advanced stats start visible (for XUI preview tool's purposes) + //pAdvancedStatsTextBox->setVisible(FALSE); + //LLRect rect = getRect(); + //reshape(rect.getWidth(), rect.getHeight() - pAdvancedStatsTextBox->getRect().getHeight() - ADVANCED_VPAD, FALSE); + if (pMotion) + { + LLTextBox* stats_box_left = getChild("AdvancedStatsLeft"); + LLTextBox* stats_box_right = getChild("AdvancedStatsRight"); + stats_box_left->setTextArg("[PRIORITY]", llformat("%d", pMotion->getPriority())); + stats_box_left->setTextArg("[DURATION]", llformat("%.2f", pMotion->getDuration())); + stats_box_left->setTextArg("[IS_LOOP]", (pMotion->getLoop() ? LLTrans::getString("PermYes") : LLTrans::getString("PermNo"))); + stats_box_right->setTextArg("[EASE_IN]", llformat("%.2f", pMotion->getEaseInDuration())); + stats_box_right->setTextArg("[EASE_OUT]", llformat("%.2f", pMotion->getEaseOutDuration())); + stats_box_right->setTextArg("[NUM_JOINTS]", llformat("%d", pMotion->getNumJointMotions())); + } + // return LLPreview::postBuild(); } @@ -167,8 +190,8 @@ void LLPreviewAnim::cleanup() this->mDidStart = false; getChild("Inworld")->setValue(FALSE); getChild("Locally")->setValue(FALSE); - getChild("Inworld")->setEnabled(true); - getChild("Locally")->setEnabled(true); + getChild("Inworld")->setEnabled(TRUE); + getChild("Locally")->setEnabled(TRUE); } // virtual @@ -182,3 +205,34 @@ void LLPreviewAnim::onClose(bool app_quitting) gAgent.sendAnimationRequest(item->getAssetUUID(), ANIM_REQUEST_STOP); } } + +// Improved animation preview +//void LLPreviewAnim::showAdvanced() +//{ +// BOOL was_visible = pAdvancedStatsTextBox->getVisible(); +// +// if (was_visible) +// { +// pAdvancedStatsTextBox->setVisible(FALSE); +// LLRect rect = getRect(); +// reshape(rect.getWidth(), rect.getHeight() - pAdvancedStatsTextBox->getRect().getHeight() - ADVANCED_VPAD, FALSE); +// } +// else +// { +// pAdvancedStatsTextBox->setVisible(TRUE); +// LLRect rect = getRect(); +// reshape(rect.getWidth(), rect.getHeight() + pAdvancedStatsTextBox->getRect().getHeight() + ADVANCED_VPAD, FALSE); +// +// // set text +// if (pMotion) +// { +// pAdvancedStatsTextBox->setTextArg("[PRIORITY]", llformat("%d", pMotion->getPriority())); +// pAdvancedStatsTextBox->setTextArg("[DURATION]", llformat("%.2f", pMotion->getDuration())); +// pAdvancedStatsTextBox->setTextArg("[EASE_IN]", llformat("%.2f", pMotion->getEaseInDuration())); +// pAdvancedStatsTextBox->setTextArg("[EASE_OUT]", llformat("%.2f", pMotion->getEaseOutDuration())); +// pAdvancedStatsTextBox->setTextArg("[IS_LOOP]", (pMotion->getLoop() ? LLTrans::getString("PermYes") : LLTrans::getString("PermNo"))); +// pAdvancedStatsTextBox->setTextArg("[NUM_JOINTS]", llformat("%d", pMotion->getNumJointMotions())); +// } +// } +//} +// diff --git a/indra/newview/llpreviewanim.h b/indra/newview/llpreviewanim.h index 8eaed6ca1f..df5ad99187 100644 --- a/indra/newview/llpreviewanim.h +++ b/indra/newview/llpreviewanim.h @@ -30,6 +30,9 @@ #include "llpreview.h" #include "llcharacter.h" +class LLMotion; +class LLTextBox; + class LLPreviewAnim : public LLPreview { public: @@ -40,11 +43,16 @@ public: void draw(); void cleanup(); void play(const LLSD& param); - + // Improved animation preview + //void showAdvanced(); + protected: LLUUID mItemID; bool mDidStart; + LLMotion* pMotion; + // Improved animation preview + //LLTextBox* pAdvancedStatsTextBox; }; #endif // LL_LLPREVIEWANIM_H diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp index 120b27b6df..6d2042753f 100644 --- a/indra/newview/llpreviewscript.cpp +++ b/indra/newview/llpreviewscript.cpp @@ -1214,7 +1214,10 @@ void LLScriptEdCore::updateDynamicHelp(BOOL immediate) } if (immediate || (mLiveHelpTimer.getStarted() && mLiveHelpTimer.getElapsedTimeF32() > LIVE_HELP_REFRESH_TIME)) { - std::string help_string = mEditor->getText().substr(segment->getStart(), segment->getEnd() - segment->getStart()); + // Use Wtext since segment's start/end are made for wstring and will + // result in a shift for case of multi-byte symbols inside std::string. + LLWString segment_text = mEditor->getWText().substr(segment->getStart(), segment->getEnd() - segment->getStart()); + std::string help_string = wstring_to_utf8str(segment_text); setHelpPage(help_string); mLiveHelpTimer.stop(); } diff --git a/indra/newview/llscenemonitor.cpp b/indra/newview/llscenemonitor.cpp index d7c03ac369..1b8ff621f8 100644 --- a/indra/newview/llscenemonitor.cpp +++ b/indra/newview/llscenemonitor.cpp @@ -530,157 +530,163 @@ void LLSceneMonitor::dumpToFile(std::string file_name) if (!hasResults()) return; LL_INFOS("SceneMonitor") << "Saving scene load stats to " << file_name << LL_ENDL; - - llofstream os(file_name.c_str()); - - os << std::setprecision(10); - - LLTrace::PeriodicRecording& scene_load_recording = mSceneLoadRecording.getResults(); - const U32 frame_count = scene_load_recording.getNumRecordedPeriods(); - - F64Seconds frame_time; - - os << "Stat"; - for (S32 frame = 1; frame <= frame_count; frame++) + try { - frame_time += scene_load_recording.getPrevRecording(frame_count - frame).getDuration(); - os << ", " << frame_time.value(); - } - os << '\n'; + llofstream os(file_name.c_str()); - os << "Sample period(s)"; - for (S32 frame = 1; frame <= frame_count; frame++) - { - frame_time = scene_load_recording.getPrevRecording(frame_count - frame).getDuration(); - os << ", " << frame_time.value(); - } - os << '\n'; + os << std::setprecision(10); + LLTrace::PeriodicRecording& scene_load_recording = mSceneLoadRecording.getResults(); + const U32 frame_count = scene_load_recording.getNumRecordedPeriods(); - typedef LLTrace::StatType trace_count; - for (auto& it : trace_count::instance_snapshot()) - { - std::ostringstream row; - row << std::setprecision(10); - - row << it.getName(); - - const char* unit_label = it.getUnitLabel(); - if(unit_label[0]) - { - row << "(" << unit_label << ")"; - } - - S32 samples = 0; + F64Seconds frame_time; + os << "Stat"; for (S32 frame = 1; frame <= frame_count; frame++) { - LLTrace::Recording& recording = scene_load_recording.getPrevRecording(frame_count - frame); - samples += recording.getSampleCount(it); - row << ", " << recording.getSum(it); + frame_time += scene_load_recording.getPrevRecording(frame_count - frame).getDuration(); + os << ", " << frame_time.value(); } - - row << '\n'; - - if (samples > 0) - { - os << row.str(); - } - } - - typedef LLTrace::StatType trace_event; - - for (auto& it : trace_event::instance_snapshot()) - { - std::ostringstream row; - row << std::setprecision(10); - row << it.getName(); - - const char* unit_label = it.getUnitLabel(); - if(unit_label[0]) - { - row << "(" << unit_label << ")"; - } - - S32 samples = 0; - - for (S32 frame = 1; frame <= frame_count; frame++) - { - LLTrace::Recording& recording = scene_load_recording.getPrevRecording(frame_count - frame); - samples += recording.getSampleCount(it); - F64 mean = recording.getMean(it); - if (llisnan(mean)) - { - row << ", n/a"; - } - else - { - row << ", " << mean; - } - } - - row << '\n'; - - if (samples > 0) - { - os << row.str(); - } - } - - typedef LLTrace::StatType trace_sample; - - for (auto& it : trace_sample::instance_snapshot()) - { - std::ostringstream row; - row << std::setprecision(10); - row << it.getName(); - - const char* unit_label = it.getUnitLabel(); - if(unit_label[0]) - { - row << "(" << unit_label << ")"; - } - - S32 samples = 0; - - for (S32 frame = 1; frame <= frame_count; frame++) - { - LLTrace::Recording& recording = scene_load_recording.getPrevRecording(frame_count - frame); - samples += recording.getSampleCount(it); - F64 mean = recording.getMean(it); - if (llisnan(mean)) - { - row << ", n/a"; - } - else - { - row << ", " << mean; - } - } - - row << '\n'; - - if (samples > 0) - { - os << row.str(); - } - } - - typedef LLTrace::StatType trace_mem; - for (auto& it : trace_mem::instance_snapshot()) - { - os << it.getName() << "(KiB)"; - - for (S32 frame = 1; frame <= frame_count; frame++) - { - os << ", " << scene_load_recording.getPrevRecording(frame_count - frame).getMax(it).valueInUnits(); - } - os << '\n'; - } - os.flush(); - os.close(); + os << "Sample period(s)"; + for (S32 frame = 1; frame <= frame_count; frame++) + { + frame_time = scene_load_recording.getPrevRecording(frame_count - frame).getDuration(); + os << ", " << frame_time.value(); + } + os << '\n'; + + + typedef LLTrace::StatType trace_count; + for (auto& it : trace_count::instance_snapshot()) + { + std::ostringstream row; + row << std::setprecision(10); + + row << it.getName(); + + const char* unit_label = it.getUnitLabel(); + if (unit_label[0]) + { + row << "(" << unit_label << ")"; + } + + S32 samples = 0; + + for (S32 frame = 1; frame <= frame_count; frame++) + { + LLTrace::Recording& recording = scene_load_recording.getPrevRecording(frame_count - frame); + samples += recording.getSampleCount(it); + row << ", " << recording.getSum(it); + } + + row << '\n'; + + if (samples > 0) + { + os << row.str(); + } + } + + typedef LLTrace::StatType trace_event; + + for (auto& it : trace_event::instance_snapshot()) + { + std::ostringstream row; + row << std::setprecision(10); + row << it.getName(); + + const char* unit_label = it.getUnitLabel(); + if (unit_label[0]) + { + row << "(" << unit_label << ")"; + } + + S32 samples = 0; + + for (S32 frame = 1; frame <= frame_count; frame++) + { + LLTrace::Recording& recording = scene_load_recording.getPrevRecording(frame_count - frame); + samples += recording.getSampleCount(it); + F64 mean = recording.getMean(it); + if (llisnan(mean)) + { + row << ", n/a"; + } + else + { + row << ", " << mean; + } + } + + row << '\n'; + + if (samples > 0) + { + os << row.str(); + } + } + + typedef LLTrace::StatType trace_sample; + + for (auto& it : trace_sample::instance_snapshot()) + { + std::ostringstream row; + row << std::setprecision(10); + row << it.getName(); + + const char* unit_label = it.getUnitLabel(); + if (unit_label[0]) + { + row << "(" << unit_label << ")"; + } + + S32 samples = 0; + + for (S32 frame = 1; frame <= frame_count; frame++) + { + LLTrace::Recording& recording = scene_load_recording.getPrevRecording(frame_count - frame); + samples += recording.getSampleCount(it); + F64 mean = recording.getMean(it); + if (llisnan(mean)) + { + row << ", n/a"; + } + else + { + row << ", " << mean; + } + } + + row << '\n'; + + if (samples > 0) + { + os << row.str(); + } + } + + typedef LLTrace::StatType trace_mem; + for (auto& it : trace_mem::instance_snapshot()) + { + os << it.getName() << "(KiB)"; + + for (S32 frame = 1; frame <= frame_count; frame++) + { + os << ", " << scene_load_recording.getPrevRecording(frame_count - frame).getMax(it).valueInUnits(); + } + + os << '\n'; + } + + os.flush(); + os.close(); + } + catch (const std::ios_base::failure &e) + { + LL_WARNS() << "Unable to dump scene monitor results: " << e.what() << LL_ENDL; + } } //------------------------------------------------------------------------------------------------------------- diff --git a/indra/newview/llscripteditor.cpp b/indra/newview/llscripteditor.cpp index 645d944fcc..82f288824f 100644 --- a/indra/newview/llscripteditor.cpp +++ b/indra/newview/llscripteditor.cpp @@ -322,3 +322,39 @@ void LLScriptEditor::drawSelectionBackground() } } } + +// Improved Home-key behavior +//virtual +void LLScriptEditor::startOfLine() +{ + const LLWString& text = getWText(); + const S32 line_start_pos = mCursorPos - getLineOffsetFromDocIndex(mCursorPos); + + S32 line_end_pos; + S32 line = getLineNumFromDocIndex(mCursorPos); + S32 num_lines = getLineCount(); + if (line + 1 >= num_lines) + { + line_end_pos = getLength(); + } + else + { + line_end_pos = getLineStart(line + 1) - 1; + } + + S32 trimmed_line_start_pos = line_start_pos; + while (trimmed_line_start_pos < line_end_pos && LLStringOps::isSpace(text[trimmed_line_start_pos])) + { + ++trimmed_line_start_pos; + } + + if (mCursorPos != trimmed_line_start_pos || mCursorPos == line_start_pos) + { + setCursorPos(trimmed_line_start_pos); + } + else if (mCursorPos == trimmed_line_start_pos) + { + setCursorPos(line_start_pos); + } +} +// diff --git a/indra/newview/llscripteditor.h b/indra/newview/llscripteditor.h index 0f84dffb7c..795871ca45 100644 --- a/indra/newview/llscripteditor.h +++ b/indra/newview/llscripteditor.h @@ -45,6 +45,10 @@ public: // LLView override virtual void draw(); + + // Improved Home-key behavior + // LLTextBase override + virtual void startOfLine(); void initKeywords(); void loadKeywords(); @@ -67,8 +71,9 @@ private: void drawLineNumbers(); /* virtual */ void updateSegments(); /* virtual */ void drawSelectionBackground(); - void loadKeywords(const std::string& filename_keywords, - const std::string& filename_colors); + // Doesn't exist + //void loadKeywords(const std::string& filename_keywords, + // const std::string& filename_colors); LLKeywords mKeywords; bool mShowLineNumbers; diff --git a/indra/newview/llskinningutil.cpp b/indra/newview/llskinningutil.cpp index d1e3e9b943..7e40bffc4e 100644 --- a/indra/newview/llskinningutil.cpp +++ b/indra/newview/llskinningutil.cpp @@ -132,47 +132,52 @@ void LLSkinningUtil::scrubInvalidJoints(LLVOAvatar *avatar, LLMeshSkinInfo* skin // Per frame SkinningMatrix Caching //void LLSkinningUtil::initSkinningMatrixPalette( -// LLMatrix4* mat, -// S32 count, -// const LLMeshSkinInfo* skin, -// LLVOAvatar *avatar) +// LLMatrix4* mat, +// S32 count, +// const LLMeshSkinInfo* skin, +// LLVOAvatar *avatar) //{ -// initJointNums(const_cast(skin), avatar); -// for (U32 j = 0; j < count; ++j) -// { -// LLJoint *joint = avatar->getJoint(skin->mJointNums[j]); -// llassert(joint); -// if (joint) -// { +// initJointNums(const_cast(skin), avatar); +// for (U32 j = 0; j < count; ++j) +// { +// S32 joint_num = skin->mJointNums[j]; +// LLJoint * joint = NULL; +// if (joint_num >= 0 && joint_num < LL_CHARACTER_MAX_ANIMATED_JOINTS) +// { +// joint = avatar->getJoint(joint_num); +// } +// llassert(joint); +// if (joint) +// { //#ifdef MAT_USE_SSE -// LLMatrix4a bind, world, res; -// bind.loadu(skin->mInvBindMatrix[j]); -// world.loadu(joint->getWorldMatrix()); -// matMul(bind, world, res); -// memcpy(mat[j].mMatrix, res.mMatrix, 16 * sizeof(float)); +// LLMatrix4a bind, world, res; +// bind.loadu(skin->mInvBindMatrix[j]); +// world.loadu(joint->getWorldMatrix()); +// matMul(bind, world, res); +// memcpy(mat[j].mMatrix, res.mMatrix, 16 * sizeof(float)); //#else -// mat[j] = skin->mInvBindMatrix[j]; -// mat[j] *= joint->getWorldMatrix(); +// mat[j] = skin->mInvBindMatrix[j]; +// mat[j] *= joint->getWorldMatrix(); //#endif -// } -// else -// { -// mat[j] = skin->mInvBindMatrix[j]; +// } +// else +// { +// mat[j] = skin->mInvBindMatrix[j]; //#if DEBUG_SKINNING -// // This shouldn't happen - in mesh upload, skinned -// // rendering should be disabled unless all joints are -// // valid. In other cases of skinned rendering, invalid -// // joints should already have been removed during scrubInvalidJoints(). -// LL_WARNS_ONCE("Avatar") << avatar->getFullname() -// << " rigged to invalid joint name " << skin->mJointNames[j] -// << " num " << skin->mJointNums[j] << LL_ENDL; -// LL_WARNS_ONCE("Avatar") << avatar->getFullname() -// << " avatar build state: isBuilt() " << avatar->isBuilt() -// << " mInitFlags " << avatar->mInitFlags << LL_ENDL; +// // This shouldn't happen - in mesh upload, skinned +// // rendering should be disabled unless all joints are +// // valid. In other cases of skinned rendering, invalid +// // joints should already have been removed during scrubInvalidJoints(). +// LL_WARNS_ONCE("Avatar") << avatar->getFullname() +// << " rigged to invalid joint name " << skin->mJointNames[j] +// << " num " << skin->mJointNums[j] << LL_ENDL; +// LL_WARNS_ONCE("Avatar") << avatar->getFullname() +// << " avatar build state: isBuilt() " << avatar->isBuilt() +// << " mInitFlags " << avatar->mInitFlags << LL_ENDL; //#endif -// dump_avatar_and_skin_state("initSkinningMatrixPalette joint not found", avatar, skin); -// } -// } +// dump_avatar_and_skin_state("initSkinningMatrixPalette joint not found", avatar, skin); +// } +// } //} #ifndef LL_RELEASE_FOR_DOWNLOAD @@ -186,44 +191,49 @@ void LLSkinningUtil::initSkinningMatrixPalette( LLVOAvatar *avatar) { #ifndef LL_RELEASE_FOR_DOWNLOAD - // This timer is too hot for normal use (though better now with caching) - LL_RECORD_BLOCK_TIME(FTM_SKINNING_INIT); + // This timer is too hot for normal use (though better now with caching) + LL_RECORD_BLOCK_TIME(FTM_SKINNING_INIT); #endif - LLMatrix4a bind[LL_MAX_JOINTS_PER_MESH_OBJECT]; - LLMatrix4a world[LL_MAX_JOINTS_PER_MESH_OBJECT]; + LLMatrix4a bind[LL_MAX_JOINTS_PER_MESH_OBJECT]; + LLMatrix4a world[LL_MAX_JOINTS_PER_MESH_OBJECT]; - initJointNums(const_cast(skin), avatar); + initJointNums(const_cast(skin), avatar); // TODO: Refactored to encourage the compiler to optimise better but it's too old and stubborn. Need to hand tool the SIMD. // TODO: There are two overheads in this function casued by the unaligned loads. use Matrix4a // TODO: getWorldMatrix forces a reverse recursion up through the skelly. Check if this is happening efficiently. - for (U32 j = 0; j < count; ++j) + for (U32 j = 0; j < count; ++j) { - LLJoint *joint = avatar->getJoint(skin->mJointNums[j]); - if (joint) - { - bind[j].loadu(skin->mInvBindMatrix[j]); - world[j].loadu(joint->getWorldMatrix()); - matMul(bind[j], world[j], mat[j]); - } - else - { - mat[j].loadu(skin->mInvBindMatrix[j]); + S32 joint_num = skin->mJointNums[j]; + LLJoint * joint = NULL; + if (joint_num >= 0 && joint_num < LL_CHARACTER_MAX_ANIMATED_JOINTS) + { + joint = avatar->getJoint(joint_num); + } + if (joint) + { + bind[j].loadu(skin->mInvBindMatrix[j]); + world[j].loadu(joint->getWorldMatrix()); + matMul(bind[j], world[j], mat[j]); + } + else + { + mat[j].loadu(skin->mInvBindMatrix[j]); #if DEBUG_SKINNING - // This shouldn't happen - in mesh upload, skinned - // rendering should be disabled unless all joints are - // valid. In other cases of skinned rendering, invalid - // joints should already have been removed during scrubInvalidJoints(). - // Beq note - Oct 2018 Animesh - Many rigged meshes still fail here. ('mElbowLeeft' typo in the rigging data) - LL_WARNS_ONCE("Avatar") << avatar->getFullname() - << " rigged to invalid joint name " << skin->mJointNames[j] - << " num " << skin->mJointNums[j] << LL_ENDL; - LL_WARNS_ONCE("Avatar") << avatar->getFullname() - << " avatar build state: isBuilt() " << avatar->isBuilt() - << " mInitFlags " << avatar->mInitFlags << LL_ENDL; + // This shouldn't happen - in mesh upload, skinned + // rendering should be disabled unless all joints are + // valid. In other cases of skinned rendering, invalid + // joints should already have been removed during scrubInvalidJoints(). + // Beq note - Oct 2018 Animesh - Many rigged meshes still fail here. ('mElbowLeeft' typo in the rigging data) + LL_WARNS_ONCE("Avatar") << avatar->getFullname() + << " rigged to invalid joint name " << skin->mJointNames[j] + << " num " << skin->mJointNums[j] << LL_ENDL; + LL_WARNS_ONCE("Avatar") << avatar->getFullname() + << " avatar build state: isBuilt() " << avatar->isBuilt() + << " mInitFlags " << avatar->mInitFlags << LL_ENDL; #endif - } + } //LL_DEBUGS("Skinning") << "[" << avatar->getFullname() << "] joint(" << skin->mJointNames[j] << ") matices bind(" << bind << ") world(" << world << ")" << LL_ENDL; } } @@ -232,7 +242,7 @@ void LLSkinningUtil::initSkinningMatrixPalette( void LLSkinningUtil::checkSkinWeights(LLVector4a* weights, U32 num_vertices, const LLMeshSkinInfo* skin) { #if DEBUG_SKINNING - const S32 max_joints = skin->mJointNames.size(); + const S32 max_joints = skin->mJointNames.size(); for (U32 j=0; j 0.0f && num_joints > joint_index) { S32 joint_num = skin->mJointNums[joint_index]; diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 7109ad6013..bc0fd281b3 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -4549,11 +4549,6 @@ bool process_login_success_response(U32 &first_sim_size_x, U32 &first_sim_size_y } // Request the map server url - // Non-agni grids have a different default location. - if (LLGridManager::getInstance()->isInSLBeta()) - { - gSavedSettings.setString("MapServerURL", "http://test.map.secondlife.com.s3.amazonaws.com/"); - } std::string map_server_url = response["map-server-url"]; if(!map_server_url.empty()) { diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp index db298d144d..b01e287de3 100644 --- a/indra/newview/lltoolpie.cpp +++ b/indra/newview/lltoolpie.cpp @@ -1003,13 +1003,51 @@ BOOL LLToolPie::handleDoubleClick(S32 x, S32 y, MASK mask) return FALSE; } +// Restore "Hover Tips on All Objects" toggle + +// static bool needs_tooltip(LLSelectNode* nodep) +// { +// if (!nodep || !nodep->mValid) +// return false; +// return true; +// } + static bool needs_tooltip(LLSelectNode* nodep) { - if (!nodep || !nodep->mValid) + if (!nodep || !nodep->mValid) return false; - return true; + + LLViewerObject* object = nodep->getObject(); + LLViewerObject *parent = (LLViewerObject *)object->getParent(); + if (object->flagHandleTouch() + || (parent && parent->flagHandleTouch()) + || object->flagTakesMoney() + || (parent && parent->flagTakesMoney()) + || object->flagAllowInventoryAdd() + ) + { + return true; + } + + U8 click_action = final_click_action(object); + if (click_action != 0) + { + return true; + } + + if (nodep->mValid) + { + bool anyone_copy = anyone_copy_selection(nodep); + bool for_sale = for_sale_selection(nodep); + if (anyone_copy || for_sale) + { + return true; + } + } + return false; } +// BOOL LLToolPie::handleTooltipLand(std::string line, std::string tooltip_msg) { diff --git a/indra/newview/llviewerassetstorage.cpp b/indra/newview/llviewerassetstorage.cpp index 5f6f281e30..6d009c0a8c 100644 --- a/indra/newview/llviewerassetstorage.cpp +++ b/indra/newview/llviewerassetstorage.cpp @@ -50,8 +50,8 @@ /// LLViewerAssetRequest ///---------------------------------------------------------------------------- - // There is also PoolSizeVAssetStorage value in setting that should mirror this name -static const std::string VIEWER_ASSET_STORAGE_CORO_POOL = "VAssetStorage"; + // There is also PoolSizeAssetStorage value in setting that should mirror this name +static const std::string VIEWER_ASSET_STORAGE_CORO_POOL = "AssetStorage"; /** * @brief Local class to encapsulate asset fetch requests with a timestamp. @@ -134,6 +134,14 @@ LLViewerAssetStorage::~LLViewerAssetStorage() // This class has dedicated coroutine pool, clean it up, otherwise coroutines will crash later. LLCoprocedureManager::instance().close(VIEWER_ASSET_STORAGE_CORO_POOL); } + + while (mCoroWaitList.size() > 0) + { + CoroWaitList &request = mCoroWaitList.front(); + // Clean up pending downloads, delete request and trigger callbacks + removeAndCallbackPendingDownloads(request.mId, request.mType, request.mId, request.mType, LL_ERR_NOERR, LLExtStat::NONE); + mCoroWaitList.pop_front(); + } } // virtual @@ -342,6 +350,29 @@ void LLViewerAssetStorage::storeAssetData( } } +void LLViewerAssetStorage::checkForTimeouts() +{ + LLAssetStorage::checkForTimeouts(); + + // Restore requests + LLCoprocedureManager* manager = LLCoprocedureManager::getInstance(); + while (mCoroWaitList.size() > 0 + && manager->count(VIEWER_ASSET_STORAGE_CORO_POOL) < LLCoprocedureManager::DEFAULT_QUEUE_SIZE) + { + CoroWaitList &request = mCoroWaitList.front(); + + // [UDP Assets] + //bool with_http = true; + //bool is_temp = false; + //LLViewerAssetStatsFF::record_enqueue(request.mType, with_http, is_temp); + // [UDP Assets] + + manager->enqueueCoprocedure(VIEWER_ASSET_STORAGE_CORO_POOL, "LLViewerAssetStorage::assetRequestCoro", + boost::bind(&LLViewerAssetStorage::assetRequestCoro, this, request.mRequest, request.mId, request.mType, request.mCallback, request.mUserData)); + + mCoroWaitList.pop_front(); + } +} /** * @brief Allocate and queue an asset fetch request for the viewer @@ -399,14 +430,22 @@ void LLViewerAssetStorage::queueRequestHttp( // This is the same as the current UDP logic - don't re-request a duplicate. if (!duplicate) { - // [UDP Assets] - //bool with_http = true; - //bool is_temp = false; - //LLViewerAssetStatsFF::record_enqueue(atype, with_http, is_temp); - // [UDP Assets] + // Coroutine buffer has fixed size (synchronization buffer, so we have no alternatives), so buffer any request above limit + if (LLCoprocedureManager::instance().count(VIEWER_ASSET_STORAGE_CORO_POOL) < LLCoprocedureManager::DEFAULT_QUEUE_SIZE) + { + // [UDP Assets] + //bool with_http = true; + //bool is_temp = false; + //LLViewerAssetStatsFF::record_enqueue(atype, with_http, is_temp); + // [UDP Assets] - LLCoprocedureManager::instance().enqueueCoprocedure(VIEWER_ASSET_STORAGE_CORO_POOL,"LLViewerAssetStorage::assetRequestCoro", - boost::bind(&LLViewerAssetStorage::assetRequestCoro, this, req, uuid, atype, callback, user_data)); + LLCoprocedureManager::instance().enqueueCoprocedure(VIEWER_ASSET_STORAGE_CORO_POOL, "LLViewerAssetStorage::assetRequestCoro", + boost::bind(&LLViewerAssetStorage::assetRequestCoro, this, req, uuid, atype, callback, user_data)); + } + else + { + mCoroWaitList.emplace_back(req, uuid, atype, callback, user_data); + } } } diff --git a/indra/newview/llviewerassetstorage.h b/indra/newview/llviewerassetstorage.h index 972c89de34..af7fbb5fbf 100644 --- a/indra/newview/llviewerassetstorage.h +++ b/indra/newview/llviewerassetstorage.h @@ -43,7 +43,7 @@ public: ~LLViewerAssetStorage(); - virtual void storeAssetData( + void storeAssetData( const LLTransactionID& tid, LLAssetType::EType atype, LLStoreAssetCallback callback, @@ -52,9 +52,9 @@ public: bool is_priority = false, bool store_local = false, bool user_waiting=FALSE, - F64Seconds timeout=LL_ASSET_STORAGE_TIMEOUT); - - virtual void storeAssetData( + F64Seconds timeout=LL_ASSET_STORAGE_TIMEOUT) override; + + void storeAssetData( const std::string& filename, const LLTransactionID& tid, LLAssetType::EType type, @@ -63,16 +63,17 @@ public: bool temp_file = false, bool is_priority = false, bool user_waiting=FALSE, - F64Seconds timeout=LL_ASSET_STORAGE_TIMEOUT); + F64Seconds timeout=LL_ASSET_STORAGE_TIMEOUT) override; + + void checkForTimeouts() override; protected: - // virtual void _queueDataRequest(const LLUUID& uuid, LLAssetType::EType type, LLGetAssetCallback callback, void *user_data, BOOL duplicate, - BOOL is_priority); + BOOL is_priority) override; void queueRequestHttp(const LLUUID& uuid, LLAssetType::EType type, @@ -91,8 +92,35 @@ protected: std::string getAssetURL(const std::string& cap_url, const LLUUID& uuid, LLAssetType::EType atype); - void logAssetStorageInfo(); - + void logAssetStorageInfo() override; + + // Asset storage works through coroutines and coroutines have limited queue capacity + // This class is meant to temporary store requests when fiber's queue is full + class CoroWaitList + { + public: + CoroWaitList(LLViewerAssetRequest *req, + const LLUUID& uuid, + LLAssetType::EType atype, + LLGetAssetCallback &callback, + void *user_data) + : mRequest(req), + mId(uuid), + mType(atype), + mCallback(callback), + mUserData(user_data) + { + } + + LLViewerAssetRequest* mRequest; + LLUUID mId; + LLAssetType::EType mType; + LLGetAssetCallback mCallback; + void *mUserData; + }; + typedef std::list wait_list_t; + wait_list_t mCoroWaitList; + std::string mViewerAssetUrl; S32 mAssetCoroCount; S32 mCountRequests; diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 77376b74e8..87b7f7ed90 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -6625,7 +6625,7 @@ class LLToolsSelectNextPartFace : public view_listener_t new_te = to_select->getNumTEs() - 1; } } - LLSelectMgr::getInstance()->addAsIndividual(to_select, new_te, FALSE); + LLSelectMgr::getInstance()->selectObjectOnly(to_select, new_te); } else { diff --git a/indra/newview/llviewernetwork.cpp b/indra/newview/llviewernetwork.cpp index df1c93733b..3daf2621a5 100644 --- a/indra/newview/llviewernetwork.cpp +++ b/indra/newview/llviewernetwork.cpp @@ -136,7 +136,7 @@ void LLGridManager::initialize(const std::string& grid_file) "https://secondlife.aditi.lindenlab.com/helpers/", DEFAULT_LOGIN_PAGE, SL_UPDATE_QUERY_URL, - "https://my.aditi.lindenlab.com/", + "https://my.secondlife-beta.com/", "Aditi"); // dump example grid file... diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 00deddbf73..4199d5a0fe 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -5034,22 +5034,78 @@ void LLViewerObject::refreshBakeTexture() } } +void LLViewerObject::updateDiffuseMatParams(const U8 te, LLMaterial* mat, LLViewerTexture *imagep, bool baked_texture) +{ + // Objects getting non-alpha texture and alpha mask can result in graphical bugs, like white or red alphas. + // To resolve the issue this function provides image format to material and based on format material's + // getDiffuseAlphaModeRender() function will decide what value to provide to render + // + // Unfortunately LLMaterial has no access to diffuse image, so we have to set this data in LLViewerObject + // regardles of object being used/seen or frequency of image-updates. + mat->setDiffuseBaked(baked_texture); + + if (!baked_texture) + { + if (imagep->isMissingAsset()) + { + mat->setDiffuseFormatPrimary(0); + } + else if (0 == imagep->getPrimaryFormat()) + { + // We don't have information about this texture, wait for it + mWaitingTextureInfo.insert(uuid_material_mmap_t::value_type(imagep->getID(), material_info(LLRender::DIFFUSE_MAP, te))); + // Temporary assume RGBA image + mat->setDiffuseFormatPrimary(GL_RGBA); + } + else + { + mat->setDiffuseFormatPrimary(imagep->getPrimaryFormat()); + } + } +} + +S32 LLViewerObject::setDiffuseImageAndParams(const U8 te, LLViewerTexture *imagep) +{ + LLUUID new_id = imagep->getID(); + S32 retval = LLPrimitive::setTETexture(te, new_id); + + LLTextureEntry* tep = getTE(te); + LLUUID old_image_id = tep->getID(); + + LLViewerTexture* baked_texture = getBakedTextureForMagicId(new_id); + mTEImages[te] = baked_texture ? baked_texture : imagep; + updateAvatarMeshVisibility(new_id, old_image_id); + + LLMaterial* mat = tep->getMaterialParams(); + if (mat) + { + // Don't update format from texture (and don't shedule one) if material has no alpha mode set, + // just assume RGBA format, format will get updated with setTEMaterialParams call if mode changes + if (mat->getDiffuseAlphaMode() != LLMaterial::DIFFUSE_ALPHA_MODE_NONE) + { + bool baked = baked_texture != NULL; + updateDiffuseMatParams(te, mat, imagep, baked); + } + else + { + mat->setDiffuseFormatPrimary(GL_RGBA); + } + } + + setChanged(TEXTURE); + if (mDrawable.notNull()) + { + gPipeline.markTextured(mDrawable); + } + + return retval; +} + void LLViewerObject::setTEImage(const U8 te, LLViewerTexture *imagep) { if (mTEImages[te] != imagep) { - LLUUID old_image_id = getTE(te) ? getTE(te)->getID() : LLUUID::null; - - LLPrimitive::setTETexture(te, imagep->getID()); - - LLViewerTexture* baked_texture = getBakedTextureForMagicId(imagep->getID()); - mTEImages[te] = baked_texture ? baked_texture : imagep; - updateAvatarMeshVisibility(imagep->getID(), old_image_id); - setChanged(TEXTURE); - if (mDrawable.notNull()) - { - gPipeline.markTextured(mDrawable); - } + setDiffuseImageAndParams(te, imagep); } } @@ -5061,15 +5117,7 @@ S32 LLViewerObject::setTETextureCore(const U8 te, LLViewerTexture *image) if (uuid != getTEref(te).getID() || uuid == LLUUID::null) { - retval = LLPrimitive::setTETexture(te, uuid); - LLViewerTexture* baked_texture = getBakedTextureForMagicId(uuid); - mTEImages[te] = baked_texture ? baked_texture : image; - updateAvatarMeshVisibility(uuid,old_image_id); - setChanged(TEXTURE); - if (mDrawable.notNull()) - { - gPipeline.markTextured(mDrawable); - } + retval = setDiffuseImageAndParams(te, image); } return retval; } @@ -5364,6 +5412,29 @@ S32 LLViewerObject::setTEMaterialParams(const U8 te, const LLMaterialPtr pMateri return 0; } + if (pMaterialParams.notNull() + && pMaterialParams->getDiffuseAlphaMode() != LLMaterial::DIFFUSE_ALPHA_MODE_NONE) + { + // Don't update if no alpha is set. If alpha changes, this function will run again, + // no point in sheduling additional texture callbacks (in updateDiffuseMatParams) + LLTextureEntry* tex_entry = getTE(te); + bool is_baked = tex_entry && LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(tex_entry->getID()); + + LLViewerTexture *img_diffuse = getTEImage(te); + llassert(NULL != img_diffuse); + + if (NULL != img_diffuse) + { + // Will modify alpha mask provided to renderer to fit image + updateDiffuseMatParams(te, pMaterialParams.get(), img_diffuse, is_baked); + } + else + { + LLMaterial *mat = pMaterialParams.get(); // to avoid const + mat->setDiffuseFormatPrimary(0); + } + } + retval = LLPrimitive::setTEMaterialParams(te, pMaterialParams); LL_DEBUGS("Material") << "Changing material params for te " << (S32)te << ", object " << mID @@ -5376,6 +5447,84 @@ S32 LLViewerObject::setTEMaterialParams(const U8 te, const LLMaterialPtr pMateri return retval; } +bool LLViewerObject::notifyAboutCreatingTexture(LLViewerTexture *texture) +{ + // Confirmation about texture creation, check wait-list + // and make changes, or return false + + std::pair range = mWaitingTextureInfo.equal_range(texture->getID()); + + bool refresh_materials = false; + + // RGB textures without alpha channels won't work right with alpha, + // we provide format to material for material to decide when to drop alpha + for (uuid_material_mmap_t::iterator range_it = range.first; range_it != range.second; ++range_it) + { + LLMaterialPtr cur_material = getTEMaterialParams(range_it->second.te); + if (cur_material.notNull() + && LLRender::DIFFUSE_MAP == range_it->second.map) + { + U32 format = texture->getPrimaryFormat(); + if (format != cur_material->getDiffuseFormatPrimary()) + { + cur_material->setDiffuseFormatPrimary(format); + refresh_materials = true; + } + } + } //for + + if (refresh_materials) + { + LLViewerObject::refreshMaterials(); + } + + //clear wait-list + mWaitingTextureInfo.erase(range.first, range.second); + + return refresh_materials; +} + +bool LLViewerObject::notifyAboutMissingAsset(LLViewerTexture *texture) +{ + // When waiting information about texture it turned out to be missing. + // Confirm the state, update values accordingly + std::pair range = mWaitingTextureInfo.equal_range(texture->getID()); + if (range.first == range.second) return false; + + bool refresh_materials = false; + + for (uuid_material_mmap_t::iterator range_it = range.first; range_it != range.second; ++range_it) + { + LLMaterialPtr cur_material = getTEMaterialParams(range_it->second.te); + if (cur_material.isNull()) + continue; + + if (range_it->second.map == LLRender::DIFFUSE_MAP) + { + LLMaterialPtr cur_material = getTEMaterialParams(range_it->second.te); + if (cur_material.notNull() + && LLRender::DIFFUSE_MAP == range_it->second.map) + { + if (0 != cur_material->getDiffuseFormatPrimary()) + { + cur_material->setDiffuseFormatPrimary(0); + refresh_materials = true; + } + } + } + } //for + + if (refresh_materials) + { + LLViewerObject::refreshMaterials(); + } + + //clear wait-list + mWaitingTextureInfo.erase(range.first, range.second); + + return refresh_materials; +} + void LLViewerObject::refreshMaterials() { setChanged(TEXTURE); diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index 07498bec2b..26aaf0a73c 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -787,7 +787,12 @@ protected: void unpackParticleSource(LLDataPacker &dp, const LLUUID& owner_id, bool legacy); void deleteParticleSource(); void setParticleSource(const LLPartSysData& particle_parameters, const LLUUID& owner_id); - + + // Helper function to modify alpha mask provided to render according to image (ex: RGB image will drop alpha mask) + void updateDiffuseMatParams(const U8 te, LLMaterial* mat, LLViewerTexture *imagep, bool baked_texture); + // Shared part of code from setTEImage and setTETextureCore + S32 setDiffuseImageAndParams(const U8 te, LLViewerTexture *imagep); + private: void setNameValueList(const std::string& list); // clears nv pairs and then individually adds \n separated NV pairs from \0 terminated string void deleteTEImages(); // correctly deletes list of images @@ -920,11 +925,28 @@ public: LLJointRiggingInfoTab mJointRiggingInfoTab; + bool notifyAboutCreatingTexture(LLViewerTexture *texture); + bool notifyAboutMissingAsset(LLViewerTexture *texture); + private: LLUUID mAttachmentItemID; // ItemID of the associated object is in user inventory. EObjectUpdateType mLastUpdateType; BOOL mLastUpdateCached; + struct material_info + { + LLRender::eTexIndex map; + U8 te; + + material_info(LLRender::eTexIndex map_, U8 te_) + : map(map_) + , te(te_) + {} + }; + + typedef std::multimap uuid_material_mmap_t; + uuid_material_mmap_t mWaitingTextureInfo; + RegionCrossExtrapolate mExtrap; // improved extrapolator // export diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index 999dbaf40b..0a45c71c97 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -1262,6 +1262,15 @@ void LLViewerObjectList::fetchObjectCostsCoro(std::string url) F32 linkPhysicsCost = objectData["linked_set_physics_cost"].asReal(); gObjectList.updateObjectCost(objectId, objectCost, linkCost, physicsCost, linkPhysicsCost); + + // area search + // Update area search to have current information. + FSAreaSearch* area_search_floater = LLFloaterReg::getTypedInstance("area_search"); + if (area_search_floater) + { + area_search_floater->updateObjectCosts(objectId, objectCost, linkCost, physicsCost, linkPhysicsCost); + } + // area search } else { diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 608c95f222..af40c6bc0c 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -237,12 +237,14 @@ #if LL_WINDOWS #include // For Unicode conversion methods +#include "llwindowwin32.h" // For AltGr handling #endif #include "utilitybar.h" // Support for the classic V1 style buttons in some skins #include "exopostprocess.h" // Exodus Vignette #include "llnetmap.h" #include "lggcontactsets.h" +#include "fspanellogin.h" #include "lltracerecording.h" @@ -2605,7 +2607,6 @@ void LLViewerWindow::shutdownGL() LLViewerWindow::~LLViewerWindow() { LL_INFOS() << "Destroying Window" << LL_ENDL; - gDebugWindowProc = TRUE; // event catching, disable once we figure out cause for exit crashes destroyWindow(); delete mDebugText; @@ -2696,6 +2697,14 @@ void LLViewerWindow::reshape(S32 width, S32 height) // round up when converting coordinates to make sure there are no gaps at edge of window LLView::sForceReshape = display_scale_changed; mRootView->reshape(llceil((F32)width / mDisplayScale.mV[VX]), llceil((F32)height / mDisplayScale.mV[VY])); + if (display_scale_changed) + { + // Needs only a 'scale change' update, everything else gets handled by LLLayoutStack::updateClass() + // [FS Login Panel] + //LLPanelLogin::reshapePanel(); + FSPanelLogin::reshapePanel(); + // [FS Login Panel] + } LLView::sForceReshape = FALSE; // clear font width caches @@ -3183,9 +3192,11 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask) // of character handling. // Alt Gr can be additionally modified by Shift const MASK alt_gr = MASK_CONTROL | MASK_ALT; + LLWindowWin32 *window = static_cast(mWindow); + U32 raw_key = window->getRawWParam(); if ((mask & alt_gr) != 0 - && key >= 0x30 - && key <= 0x5A + && ((raw_key >= 0x30 && raw_key <= 0x5A) //0-9, plus normal chartacters + || (raw_key >= 0xBA && raw_key <= 0xE4)) // Misc/OEM characters that can be covered by AltGr, ex: -, =, ~ && (GetKeyState(VK_RMENU) & 0x8000) != 0 && (GetKeyState(VK_RCONTROL) & 0x8000) == 0) // ensure right control is not pressed, only left one { diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp index 637212cddd..e30dbe8da5 100644 --- a/indra/newview/llvoiceclient.cpp +++ b/indra/newview/llvoiceclient.cpp @@ -190,13 +190,13 @@ void LLVoiceClient::terminate() { if (mVoiceModule) mVoiceModule->terminate(); mVoiceModule = NULL; + m_servicePump = NULL; - // Shutdown speaker volume storage before CRT does it - if (LLSpeakerVolumeStorage::instanceExists()) - { - LLSpeakerVolumeStorage::deleteSingleton(); - } - // + // Shutdown speaker volume storage before LLSingletonBase::deleteAll() does it + if (LLSpeakerVolumeStorage::instanceExists()) + { + LLSpeakerVolumeStorage::deleteSingleton(); + } } const LLVoiceVersionInfo LLVoiceClient::getVersion() diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index 57d64e5c84..6446fff6ab 100644 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -392,7 +392,7 @@ LLVivoxVoiceClient::~LLVivoxVoiceClient() void LLVivoxVoiceClient::init(LLPumpIO *pump) { // constructor will set up LLVoiceClient::getInstance() - LLVivoxVoiceClient::getInstance()->mPump = pump; + mPump = pump; // LLCoros::instance().launch("LLVivoxVoiceClient::voiceControlCoro", // boost::bind(&LLVivoxVoiceClient::voiceControlCoro, LLVivoxVoiceClient::getInstance())); @@ -420,6 +420,7 @@ void LLVivoxVoiceClient::terminate() } sShuttingDown = true; + mPump = NULL; // Delete useless Vivox logs on logout if (gSavedSettings.getString("VivoxDebugLevel") == "0") @@ -1052,10 +1053,15 @@ bool LLVivoxVoiceClient::startAndLaunchDaemon() llcoro::suspendUntilTimeout(UPDATE_THROTTLE_SECONDS); - while (!mPump) - { // Can't do this until we have the pump available. + while (!mPump && !sShuttingDown) + { // Can't use the pump until we have it available. llcoro::suspend(); } + + if (sShuttingDown) + { + return false; + } // MBW -- Note to self: pumps and pipes examples in // indra/test/io.cpp @@ -1068,8 +1074,10 @@ bool LLVivoxVoiceClient::startAndLaunchDaemon() readChain.push_back(LLIOPipe::ptr_t(new LLIOSocketReader(mSocket))); readChain.push_back(LLIOPipe::ptr_t(new LLVivoxProtocolParser())); + mPump->addChain(readChain, NEVER_CHAIN_EXPIRY_SECS); + //--------------------------------------------------------------------- llcoro::suspendUntilTimeout(UPDATE_THROTTLE_SECONDS); @@ -1092,6 +1100,11 @@ bool LLVivoxVoiceClient::provisionVoiceAccount() // *TODO* Pump a message for wake up. llcoro::suspend(); } + + if (sShuttingDown) + { + return false; + } std::string url = gAgent.getRegionCapability("ProvisionVoiceAccountRequest"); diff --git a/indra/newview/llvotree.cpp b/indra/newview/llvotree.cpp index f128301b2b..a84a5daf3d 100644 --- a/indra/newview/llvotree.cpp +++ b/indra/newview/llvotree.cpp @@ -45,6 +45,8 @@ #include "llviewertexturelist.h" #include "llviewerobjectlist.h" #include "llviewerregion.h" +#include "llvolumemgr.h" +#include "llvovolume.h" #include "llworld.h" #include "noise.h" #include "pipeline.h" @@ -85,6 +87,9 @@ LLVOTree::LLVOTree(const LLUUID &id, const LLPCode pcode, LLViewerRegion *region mFrameCount = 0; mWind = mRegionp->mWind.getVelocity(getPositionRegion()); mTrunkLOD = 0; + + // if assert triggers, idleUpdate() needs to be revised and adjusted to new LOD levels + llassert(sMAX_NUM_TREE_LOD_LEVELS == LLVolumeLODGroup::NUM_LODS); } @@ -358,8 +363,11 @@ void LLVOTree::idleUpdate(LLAgent &agent, const F64 &time) return; } - S32 trunk_LOD = sMAX_NUM_TREE_LOD_LEVELS ; + S32 trunk_LOD = sMAX_NUM_TREE_LOD_LEVELS ; // disabled F32 app_angle = getAppAngle()*LLVOTree::sTreeFactor; + F32 distance = mDrawable->mDistanceWRTCamera * LLVOVolume::sDistanceFactor * (F_PI / 3.f); + F32 diameter = getScale().length(); // trees have very broken scale, but length rougtly outlines proper diameter + F32 sz = mBillboardScale * mBillboardRatio * diameter; for (S32 j = 0; j < sMAX_NUM_TREE_LOD_LEVELS; j++) { @@ -368,7 +376,14 @@ void LLVOTree::idleUpdate(LLAgent &agent, const F64 &time) trunk_LOD = j; break; } - } + } + + F32 tan_angle = (LLVOTree::sTreeFactor * 64 * sz) / distance; + S32 cur_detail = LLVolumeLODGroup::getDetailFromTan(ll_round(tan_angle, 0.01f)); // larger value, better quality + + // for trunk_LOD lower value means better quality, but both trunk_LOD and cur_detail have 4 levels + trunk_LOD = llmax(trunk_LOD, LLVolumeLODGroup::NUM_LODS - cur_detail - 1); + trunk_LOD = llmin(trunk_LOD, sMAX_NUM_TREE_LOD_LEVELS); if (mReferenceBuffer.isNull()) { @@ -419,8 +434,9 @@ void LLVOTree::setPixelAreaAndAngle(LLAgent &agent) LLVector3 lookAt = center - viewer_pos_agent; F32 dist = lookAt.normVec() ; F32 cos_angle_to_view_dir = lookAt * LLViewerCamera::getInstance()->getXAxis() ; - - F32 range = dist - getMinScale()/2; + F32 radius = getScale().length()*0.5f; + F32 range = dist - radius; + if (range < F_ALMOST_ZERO || isHUDAttachment()) // range == zero { mAppAngle = 180.f; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index d848810eeb..56a34f7099 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -2487,250 +2487,11 @@ S32 LLVOVolume::setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID) return res; } -bool LLVOVolume::notifyAboutCreatingTexture(LLViewerTexture *texture) -{ //Ok, here we have confirmation about texture creation, check our wait-list - //and make changes, or return false - - std::pair range = mWaitingTextureInfo.equal_range(texture->getID()); - - typedef std::map map_te_material; - map_te_material new_material; - - for(mmap_UUID_MAP_t::iterator range_it = range.first; range_it != range.second; ++range_it) - { - LLMaterialPtr cur_material = getTEMaterialParams(range_it->second.te); - - //here we just interesting in DIFFUSE_MAP only! - if(NULL != cur_material.get() && LLRender::DIFFUSE_MAP == range_it->second.map && GL_RGBA != texture->getPrimaryFormat()) - { //ok let's check the diffuse mode - switch(cur_material->getDiffuseAlphaMode()) - { - case LLMaterial::DIFFUSE_ALPHA_MODE_BLEND: - case LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE: - case LLMaterial::DIFFUSE_ALPHA_MODE_MASK: - { //uups... we have non 32 bit texture with LLMaterial::DIFFUSE_ALPHA_MODE_* => LLMaterial::DIFFUSE_ALPHA_MODE_NONE - - LLMaterialPtr mat = NULL; - map_te_material::iterator it = new_material.find(range_it->second.te); - if(new_material.end() == it) { - mat = new LLMaterial(cur_material->asLLSD()); - new_material.insert(map_te_material::value_type(range_it->second.te, mat)); - } else { - mat = it->second; - } - - mat->setDiffuseAlphaMode(LLMaterial::DIFFUSE_ALPHA_MODE_NONE); - - } break; - } //switch - } //if - } //for - - // Factor out instance() calls - LLMaterialMgr& mmgr = LLMaterialMgr::instance(); - - //setup new materials - for(map_te_material::const_iterator it = new_material.begin(), end = new_material.end(); it != end; ++it) - { - // These are placeholder materials, they shouldn't be sent to server - mmgr.setLocalMaterial(getRegion()->getRegionID(), it->second); // Factor out instance() calls - LLViewerObject::setTEMaterialParams(it->first, it->second); - } - - //clear wait-list - mWaitingTextureInfo.erase(range.first, range.second); - - return 0 != new_material.size(); -} - -bool LLVOVolume::notifyAboutMissingAsset(LLViewerTexture *texture) -{ //Ok, here if we wait information about texture and it's missing - //then depending from the texture map (diffuse, normal, or specular) - //make changes in material and confirm it. If not return false. - std::pair range = mWaitingTextureInfo.equal_range(texture->getID()); - if(range.first == range.second) return false; - - typedef std::map map_te_material; - map_te_material new_material; - - for(mmap_UUID_MAP_t::iterator range_it = range.first; range_it != range.second; ++range_it) - { - LLMaterialPtr cur_material = getTEMaterialParams(range_it->second.te); - if (cur_material.isNull()) - continue; - - switch(range_it->second.map) - { - case LLRender::DIFFUSE_MAP: - { - if(LLMaterial::DIFFUSE_ALPHA_MODE_NONE != cur_material->getDiffuseAlphaMode()) - { //missing texture + !LLMaterial::DIFFUSE_ALPHA_MODE_NONE => LLMaterial::DIFFUSE_ALPHA_MODE_NONE - LLMaterialPtr mat = NULL; - map_te_material::iterator it = new_material.find(range_it->second.te); - if(new_material.end() == it) { - mat = new LLMaterial(cur_material->asLLSD()); - new_material.insert(map_te_material::value_type(range_it->second.te, mat)); - } else { - mat = it->second; - } - - mat->setDiffuseAlphaMode(LLMaterial::DIFFUSE_ALPHA_MODE_NONE); - } - } break; - case LLRender::NORMAL_MAP: - { //missing texture => reset material texture id - LLMaterialPtr mat = NULL; - map_te_material::iterator it = new_material.find(range_it->second.te); - if(new_material.end() == it) { - mat = new LLMaterial(cur_material->asLLSD()); - new_material.insert(map_te_material::value_type(range_it->second.te, mat)); - } else { - mat = it->second; - } - - mat->setNormalID(LLUUID::null); - } break; - case LLRender::SPECULAR_MAP: - { //missing texture => reset material texture id - LLMaterialPtr mat = NULL; - map_te_material::iterator it = new_material.find(range_it->second.te); - if(new_material.end() == it) { - mat = new LLMaterial(cur_material->asLLSD()); - new_material.insert(map_te_material::value_type(range_it->second.te, mat)); - } else { - mat = it->second; - } - - mat->setSpecularID(LLUUID::null); - } break; - case LLRender::NUM_TEXTURE_CHANNELS: - //nothing to do, make compiler happy - break; - } //switch - } //for - - // Factor out instance() calls - LLMaterialMgr& mmgr = LLMaterialMgr::instance(); - - //setup new materials - for(map_te_material::const_iterator it = new_material.begin(), end = new_material.end(); it != end; ++it) - { - mmgr.setLocalMaterial(getRegion()->getRegionID(), it->second); // Factor out instance() calls - LLViewerObject::setTEMaterialParams(it->first, it->second); - } - - //clear wait-list - mWaitingTextureInfo.erase(range.first, range.second); - - return 0 != new_material.size(); -} - S32 LLVOVolume::setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams) { - LLMaterialPtr pMaterial = const_cast(pMaterialParams); + S32 res = LLViewerObject::setTEMaterialParams(te, pMaterialParams); - if(pMaterialParams) - { //check all of them according to material settings - - LLViewerTexture *img_diffuse = getTEImage(te); - LLViewerTexture *img_normal = getTENormalMap(te); - LLViewerTexture *img_specular = getTESpecularMap(te); - - llassert(NULL != img_diffuse); - - LLMaterialPtr new_material = NULL; - - //diffuse - if(NULL != img_diffuse) - { //guard - if(0 == img_diffuse->getPrimaryFormat() && !img_diffuse->isMissingAsset()) - { //ok here we don't have information about texture, let's belief and leave material settings - //but we remember this case - mWaitingTextureInfo.insert(mmap_UUID_MAP_t::value_type(img_diffuse->getID(), material_info(LLRender::DIFFUSE_MAP, te))); - } - else - { - bool bSetDiffuseNone = false; - if(img_diffuse->isMissingAsset()) - { - bSetDiffuseNone = true; - } - else - { - switch(pMaterialParams->getDiffuseAlphaMode()) - { - case LLMaterial::DIFFUSE_ALPHA_MODE_BLEND: - case LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE: - case LLMaterial::DIFFUSE_ALPHA_MODE_MASK: - { //all of them modes available only for 32 bit textures - LLTextureEntry* tex_entry = getTE(te); - bool bIsBakedImageId = false; - if (tex_entry && LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(tex_entry->getID())) - { - bIsBakedImageId = true; - } - if (GL_RGBA != img_diffuse->getPrimaryFormat() && !bIsBakedImageId) - { - bSetDiffuseNone = true; - } - } break; - } - } //else - - - if(bSetDiffuseNone) - { //upps... we should substitute this material with LLMaterial::DIFFUSE_ALPHA_MODE_NONE - new_material = new LLMaterial(pMaterialParams->asLLSD()); - new_material->setDiffuseAlphaMode(LLMaterial::DIFFUSE_ALPHA_MODE_NONE); - } - } - } - - //normal - if(LLUUID::null != pMaterialParams->getNormalID()) - { - if(img_normal && img_normal->isMissingAsset() && img_normal->getID() == pMaterialParams->getNormalID()) - { - if(!new_material) { - new_material = new LLMaterial(pMaterialParams->asLLSD()); - } - new_material->setNormalID(LLUUID::null); - } - else if(NULL == img_normal || 0 == img_normal->getPrimaryFormat()) - { //ok here we don't have information about texture, let's belief and leave material settings - //but we remember this case - mWaitingTextureInfo.insert(mmap_UUID_MAP_t::value_type(pMaterialParams->getNormalID(), material_info(LLRender::NORMAL_MAP,te))); - } - - } - - - //specular - if(LLUUID::null != pMaterialParams->getSpecularID()) - { - if(img_specular && img_specular->isMissingAsset() && img_specular->getID() == pMaterialParams->getSpecularID()) - { - if(!new_material) { - new_material = new LLMaterial(pMaterialParams->asLLSD()); - } - new_material->setSpecularID(LLUUID::null); - } - else if(NULL == img_specular || 0 == img_specular->getPrimaryFormat()) - { //ok here we don't have information about texture, let's belief and leave material settings - //but we remember this case - mWaitingTextureInfo.insert(mmap_UUID_MAP_t::value_type(pMaterialParams->getSpecularID(), material_info(LLRender::SPECULAR_MAP, te))); - } - } - - if(new_material) { - pMaterial = new_material; - LLMaterialMgr::getInstance()->setLocalMaterial(getRegion()->getRegionID(), pMaterial); - } - } - - S32 res = LLViewerObject::setTEMaterialParams(te, pMaterial); - - LL_DEBUGS("MaterialTEs") << "te " << (S32)te << " material " << ((pMaterial) ? pMaterial->asLLSD() : LLSD("null")) << " res " << res + LL_DEBUGS("MaterialTEs") << "te " << (S32)te << " material " << ((pMaterialParams) ? pMaterialParams->asLLSD() : LLSD("null")) << " res " << res << ( LLSelectMgr::getInstance()->getSelection()->contains(const_cast(this), te) ? " selected" : " not selected" ) << LL_ENDL; setChanged(ALL_CHANGED); @@ -4840,7 +4601,7 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& LLMaterial* mat = te->getMaterialParams(); if (mat) { - U8 mode = mat->getDiffuseAlphaMode(); + U8 mode = mat->getDiffuseAlphaModeRender(); if (mode == LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE || mode == LLMaterial::DIFFUSE_ALPHA_MODE_NONE @@ -5519,7 +5280,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, } draw_info->mAlphaMaskCutoff = mat->getAlphaMaskCutoff() * (1.f / 255.f); - draw_info->mDiffuseAlphaMode = mat->getDiffuseAlphaMode(); + draw_info->mDiffuseAlphaMode = mat->getDiffuseAlphaModeRender(); draw_info->mNormalMap = facep->getViewerObject()->getTENormalMap(facep->getTEOffset()); } else @@ -5922,7 +5683,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) if (mat && LLPipeline::sRenderDeferred) { - U8 alpha_mode = mat->getDiffuseAlphaMode(); + U8 alpha_mode = mat->getDiffuseAlphaModeRender(); bool is_alpha = type == LLDrawPool::POOL_ALPHA && (alpha_mode == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND || @@ -5951,7 +5712,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) else if (mat) { bool is_alpha = type == LLDrawPool::POOL_ALPHA; - U8 mode = mat->getDiffuseAlphaMode(); + U8 mode = mat->getDiffuseAlphaModeRender(); bool can_be_shiny = mode == LLMaterial::DIFFUSE_ALPHA_MODE_NONE || mode == LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE; @@ -6863,7 +6624,7 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace bool can_be_shiny = true; if (mat) { - U8 mode = mat->getDiffuseAlphaMode(); + U8 mode = mat->getDiffuseAlphaModeRender(); can_be_shiny = mode == LLMaterial::DIFFUSE_ALPHA_MODE_NONE || mode == LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE; } @@ -6885,7 +6646,7 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace // if (te->getFullbright()) { - if (mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK) + if (mat->getDiffuseAlphaModeRender() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK) { if (opaque) { @@ -6970,7 +6731,7 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace } else if (mat) { - U8 mode = mat->getDiffuseAlphaMode(); + U8 mode = mat->getDiffuseAlphaModeRender(); is_alpha = (is_alpha || (mode == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND)); @@ -7069,7 +6830,7 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace } else if (fullbright || bake_sunlight) { //fullbright - if (mat && mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK) + if (mat && mat->getDiffuseAlphaModeRender() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK) { registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK); } @@ -7091,7 +6852,7 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace else { //all around simple llassert(mask & LLVertexBuffer::MAP_NORMAL); - if (mat && mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK) + if (mat && mat->getDiffuseAlphaModeRender() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK) { //material alpha mask can be respected in non-deferred registerFace(group, facep, LLRenderPass::PASS_ALPHA_MASK); } diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index 4c68bbdd54..a046589f04 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -450,26 +450,6 @@ protected: static S32 sNumLODChanges; friend class LLVolumeImplFlexible; - -public: - bool notifyAboutCreatingTexture(LLViewerTexture *texture); - bool notifyAboutMissingAsset(LLViewerTexture *texture); - -private: - struct material_info - { - LLRender::eTexIndex map; - U8 te; - - material_info(LLRender::eTexIndex map_, U8 te_) - : map(map_) - , te(te_) - {} - }; - - typedef std::multimap mmap_UUID_MAP_t; - mmap_UUID_MAP_t mWaitingTextureInfo; - }; #endif // LL_LLVOVOLUME_H diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 0a5e59418d..f73674fe0f 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -1816,7 +1816,7 @@ U32 LLPipeline::getPoolTypeFromTE(const LLTextureEntry* te, LLViewerTexture* ima if (alpha && mat) { - switch (mat->getDiffuseAlphaMode()) + switch (mat->getDiffuseAlphaModeRender()) { case 1: alpha = true; // Material's alpha mode is set to blend. Toss it into the alpha draw pool. diff --git a/indra/newview/skins/ansastorm/colors.xml b/indra/newview/skins/ansastorm/colors.xml index 95e6325dee..e093b9e68c 100644 --- a/indra/newview/skins/ansastorm/colors.xml +++ b/indra/newview/skins/ansastorm/colors.xml @@ -640,6 +640,9 @@ + diff --git a/indra/newview/skins/ansastorm/themes/blood/colors.xml b/indra/newview/skins/ansastorm/themes/blood/colors.xml index 42650a9737..6bf84c5e92 100644 --- a/indra/newview/skins/ansastorm/themes/blood/colors.xml +++ b/indra/newview/skins/ansastorm/themes/blood/colors.xml @@ -599,6 +599,9 @@ + diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml index 954ba72caa..5701690f7d 100644 --- a/indra/newview/skins/default/colors.xml +++ b/indra/newview/skins/default/colors.xml @@ -583,6 +583,9 @@ + diff --git a/indra/newview/skins/default/xui/de/floater_buy_object.xml b/indra/newview/skins/default/xui/de/floater_buy_object.xml index fd2878d3f4..a5280b18f9 100644 --- a/indra/newview/skins/default/xui/de/floater_buy_object.xml +++ b/indra/newview/skins/default/xui/de/floater_buy_object.xml @@ -15,6 +15,9 @@ (kein Transferieren) + + Mehrfachauswahl + Inhalt: diff --git a/indra/newview/skins/default/xui/de/floater_preview_animation.xml b/indra/newview/skins/default/xui/de/floater_preview_animation.xml index 2dd47a27ad..8dda7064d7 100644 --- a/indra/newview/skins/default/xui/de/floater_preview_animation.xml +++ b/indra/newview/skins/default/xui/de/floater_preview_animation.xml @@ -3,10 +3,20 @@ Animation: [NAME] - + Beschreibung: - + + + +Priority: [PRIORITY] +Duration: [DURATION]s +Loop: [IS_LOOP] + + +Ease In: [EASE_IN]s +Ease Out: [EASE_OUT]s +Joints: [NUM_JOINTS] + diff --git a/indra/newview/skins/default/xui/en/floater_publish_classified.xml b/indra/newview/skins/default/xui/en/floater_publish_classified.xml index 322e34272c..585cf8282f 100644 --- a/indra/newview/skins/default/xui/en/floater_publish_classified.xml +++ b/indra/newview/skins/default/xui/en/floater_publish_classified.xml @@ -6,6 +6,7 @@ layout="topleft" name="publish_classified" title="Publishing Classified" + help_topic="fs_profile_edit_classified" width="320"> + tool_tip="When people have 'Hover Tips on All Objects' selected in the viewer's settings, they'll see the object description pop-up for any object under their mouse pointer. The prim description is limited to 127 bytes any string longer then that will be truncated." /> + + + @@ -2742,6 +2745,17 @@ + + + + + diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index fd3698789f..007032c10a 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -4167,6 +4167,8 @@ Finished download of raw terrain file to: [DOWNLOAD_PATH]. + Version [VERSION] is required for login. +Release notes: [URL] + Click OK to download and install. confirm Version [VERSION] has been downloaded and is ready to install. +Release notes: [URL] + Click OK to install. confirm Version [VERSION] has been downloaded and is ready to install. +Release notes: [URL] + Proceed? confirm + diff --git a/indra/newview/skins/default/xui/en/panel_preferences_sound.xml b/indra/newview/skins/default/xui/en/panel_preferences_sound.xml index fb6d6c78ee..23589e936a 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_sound.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_sound.xml @@ -1037,7 +1037,7 @@ enabled_control="EnableVoiceChat" control_name="PushToTalkToggle" height="15" - label="Toggle speak on/off when I press button in toolbar" + label="Toggle speak on/off when I press button in toolbar" layout="topleft" left="25" name="push_to_talk_toggle_check" diff --git a/indra/newview/skins/default/xui/en/sidepanel_item_info.xml b/indra/newview/skins/default/xui/en/sidepanel_item_info.xml index 22af1596eb..18fcaae6e9 100644 --- a/indra/newview/skins/default/xui/en/sidepanel_item_info.xml +++ b/indra/newview/skins/default/xui/en/sidepanel_item_info.xml @@ -155,7 +155,7 @@ name="LabelItemDesc" top_delta="-5" width="210" - tool_tip="When people have 'Hover Tips' selected in the viewer's settings, they'll see the object description pop-up for any object under their mouse pointer. The prim description is limited to 127 bytes any string longer then that will be truncated." /> + tool_tip="When people have 'Hover Tips on All Objects' selected in the viewer's settings, they'll see the object description pop-up for any object under their mouse pointer. The prim description is limited to 127 bytes any string longer then that will be truncated." /> + tool_tip="When people have 'Hover Tips on All Objects' selected in the viewer's settings, they'll see the object description pop-up for any object under their mouse pointer. The prim description is limited to 127 bytes any string longer then that will be truncated." /> Didn't find what you're looking for? Show [secondlife:///app/inventory/filters Filters]. Didn't find what you're looking for? Try [secondlife:///app/search/places/[SEARCH_TERM] Search]. Drag a landmark here to add it to your favorites. + You have no listings yet. No items found. Check the spelling of your search string and try again. You do not have a copy of this texture in your inventory Your Marketplace purchases will appear here. You may then drag them into your inventory to use them. @@ -2211,10 +2212,10 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. Also there are some other places where "generic" is used. So, let add string with name="generic" with the same value as "generic_request_error" --> - Error making request, please try again later. + Please close and reopen the conversation, or relog and try again. - Error making request, please try again later. + Please close and reopen the conversation, or relog and try again. You do not have sufficient permissions. diff --git a/indra/newview/skins/default/xui/es/floater_tools.xml b/indra/newview/skins/default/xui/es/floater_tools.xml index cdc36ef0ae..f53eb950fe 100644 --- a/indra/newview/skins/default/xui/es/floater_tools.xml +++ b/indra/newview/skins/default/xui/es/floater_tools.xml @@ -191,7 +191,7 @@ Descripción: - + Creador: diff --git a/indra/newview/skins/default/xui/es/menu_viewer.xml b/indra/newview/skins/default/xui/es/menu_viewer.xml index c814074ea8..c6b8458dfa 100644 --- a/indra/newview/skins/default/xui/es/menu_viewer.xml +++ b/indra/newview/skins/default/xui/es/menu_viewer.xml @@ -285,6 +285,7 @@ + diff --git a/indra/newview/skins/default/xui/es/panel_preferences_UI.xml b/indra/newview/skins/default/xui/es/panel_preferences_UI.xml index 6d105ad68c..4be5abc918 100644 --- a/indra/newview/skins/default/xui/es/panel_preferences_UI.xml +++ b/indra/newview/skins/default/xui/es/panel_preferences_UI.xml @@ -6,6 +6,7 @@ Bulas: + Demora en mostrar bulas: diff --git a/indra/newview/skins/default/xui/es/sidepanel_item_info.xml b/indra/newview/skins/default/xui/es/sidepanel_item_info.xml index c0ab40360b..3c8f30ee66 100644 --- a/indra/newview/skins/default/xui/es/sidepanel_item_info.xml +++ b/indra/newview/skins/default/xui/es/sidepanel_item_info.xml @@ -38,7 +38,7 @@ Descripción: - + Creador: diff --git a/indra/newview/skins/default/xui/es/sidepanel_task_info.xml b/indra/newview/skins/default/xui/es/sidepanel_task_info.xml index 4cd1fb1c5f..df826f0f37 100644 --- a/indra/newview/skins/default/xui/es/sidepanel_task_info.xml +++ b/indra/newview/skins/default/xui/es/sidepanel_task_info.xml @@ -53,7 +53,7 @@ Descripción: - + Creador: diff --git a/indra/newview/skins/default/xui/fr/control_table_contents_camera.xml b/indra/newview/skins/default/xui/fr/control_table_contents_camera.xml new file mode 100644 index 0000000000..79e4660c85 --- /dev/null +++ b/indra/newview/skins/default/xui/fr/control_table_contents_camera.xml @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/indra/newview/skins/default/xui/fr/control_table_contents_columns_basic.xml b/indra/newview/skins/default/xui/fr/control_table_contents_columns_basic.xml new file mode 100644 index 0000000000..eac7c94979 --- /dev/null +++ b/indra/newview/skins/default/xui/fr/control_table_contents_columns_basic.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/indra/newview/skins/default/xui/fr/control_table_contents_editing.xml b/indra/newview/skins/default/xui/fr/control_table_contents_editing.xml new file mode 100644 index 0000000000..b4ed03d4e6 --- /dev/null +++ b/indra/newview/skins/default/xui/fr/control_table_contents_editing.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/indra/newview/skins/default/xui/fr/control_table_contents_media.xml b/indra/newview/skins/default/xui/fr/control_table_contents_media.xml new file mode 100644 index 0000000000..cad7af52db --- /dev/null +++ b/indra/newview/skins/default/xui/fr/control_table_contents_media.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/indra/newview/skins/default/xui/fr/control_table_contents_movement.xml b/indra/newview/skins/default/xui/fr/control_table_contents_movement.xml new file mode 100644 index 0000000000..d774170974 --- /dev/null +++ b/indra/newview/skins/default/xui/fr/control_table_contents_movement.xml @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/indra/newview/skins/default/xui/fr/floater_object_weights.xml b/indra/newview/skins/default/xui/fr/floater_object_weights.xml index a258de2cff..b3486e3f83 100644 --- a/indra/newview/skins/default/xui/fr/floater_object_weights.xml +++ b/indra/newview/skins/default/xui/fr/floater_object_weights.xml @@ -1,2 +1,28 @@ - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/indra/newview/skins/default/xui/fr/floater_preferences.xml b/indra/newview/skins/default/xui/fr/floater_preferences.xml index 51518b76cf..5dcb37b214 100644 --- a/indra/newview/skins/default/xui/fr/floater_preferences.xml +++ b/indra/newview/skins/default/xui/fr/floater_preferences.xml @@ -14,8 +14,9 @@ - + + diff --git a/indra/newview/skins/default/xui/fr/floater_select_key.xml b/indra/newview/skins/default/xui/fr/floater_select_key.xml index 8b21da3f3a..ed9d7136c3 100644 --- a/indra/newview/skins/default/xui/fr/floater_select_key.xml +++ b/indra/newview/skins/default/xui/fr/floater_select_key.xml @@ -1,5 +1,24 @@ - + - Appuyez sur la touche qui contrôlera l'activation et la désactivation du chat vocal. - diff --git a/indra/newview/skins/default/xui/fr/menu_viewer.xml b/indra/newview/skins/default/xui/fr/menu_viewer.xml index e9ac21e01e..2d1ee3e931 100644 --- a/indra/newview/skins/default/xui/fr/menu_viewer.xml +++ b/indra/newview/skins/default/xui/fr/menu_viewer.xml @@ -266,6 +266,7 @@ + diff --git a/indra/newview/skins/default/xui/fr/panel_preferences_UI.xml b/indra/newview/skins/default/xui/fr/panel_preferences_UI.xml index db08c38422..3c7c3a2e77 100644 --- a/indra/newview/skins/default/xui/fr/panel_preferences_UI.xml +++ b/indra/newview/skins/default/xui/fr/panel_preferences_UI.xml @@ -4,6 +4,7 @@ Astuces : + diff --git a/indra/newview/skins/default/xui/fr/panel_preferences_controls.xml b/indra/newview/skins/default/xui/fr/panel_preferences_controls.xml new file mode 100644 index 0000000000..34383b6030 --- /dev/null +++ b/indra/newview/skins/default/xui/fr/panel_preferences_controls.xml @@ -0,0 +1,10 @@ + + + + + + + + + diff --git a/indra/newview/skins/default/xui/it/panel_preferences_UI.xml b/indra/newview/skins/default/xui/it/panel_preferences_UI.xml index 46dd91a23c..5c069eafc5 100644 --- a/indra/newview/skins/default/xui/it/panel_preferences_UI.xml +++ b/indra/newview/skins/default/xui/it/panel_preferences_UI.xml @@ -6,6 +6,7 @@ Suggerimenti al passaggio del mouse (hovertip): + diff --git a/indra/newview/skins/default/xui/it/sidepanel_item_info.xml b/indra/newview/skins/default/xui/it/sidepanel_item_info.xml index 3196ac960e..fa9b895507 100644 --- a/indra/newview/skins/default/xui/it/sidepanel_item_info.xml +++ b/indra/newview/skins/default/xui/it/sidepanel_item_info.xml @@ -35,7 +35,7 @@ Descrizione: - + Creatore: diff --git a/indra/newview/skins/default/xui/it/sidepanel_task_info.xml b/indra/newview/skins/default/xui/it/sidepanel_task_info.xml index 3e04b30cae..ff577ac5a7 100644 --- a/indra/newview/skins/default/xui/it/sidepanel_task_info.xml +++ b/indra/newview/skins/default/xui/it/sidepanel_task_info.xml @@ -53,7 +53,7 @@ Descrizione: - + Ideatore: diff --git a/indra/newview/skins/default/xui/ja/menu_viewer.xml b/indra/newview/skins/default/xui/ja/menu_viewer.xml index 78a938fd6b..c5623be4f7 100644 --- a/indra/newview/skins/default/xui/ja/menu_viewer.xml +++ b/indra/newview/skins/default/xui/ja/menu_viewer.xml @@ -317,7 +317,9 @@ + + diff --git a/indra/newview/skins/default/xui/ja/panel_preferences_UI.xml b/indra/newview/skins/default/xui/ja/panel_preferences_UI.xml index d0ce000b1b..082367489a 100644 --- a/indra/newview/skins/default/xui/ja/panel_preferences_UI.xml +++ b/indra/newview/skins/default/xui/ja/panel_preferences_UI.xml @@ -3,23 +3,31 @@ + + ヒント: + + + ヒント表示までの時間: + + + 秒 @@ -28,9 +36,13 @@ + + + + UI サイズ: @@ -58,6 +70,7 @@ + @@ -87,8 +100,11 @@ 秒 + + + ステータスバー @@ -108,9 +124,13 @@ + + + + @@ -161,8 +181,11 @@ + + + 通知の表示設定(ポップアップ、コンソール、トースト): @@ -214,15 +237,21 @@ + + + + + フォント種類: (再起動が必要) + フォントサイズ: @@ -231,6 +260,7 @@ ポイント(再起動が必要) 0がデフォルト。あまり大きいサイズはお勧めしません。 + チャットの行間: @@ -239,6 +269,7 @@ ピクセル(再起動が必要) 0が2/3系のデフォルト、2が1系のデフォルトです。 + フォルダ表示の高さ: @@ -247,7 +278,9 @@ ピクセル(再起動が必要) 20が2/3系のデフォルト、18が1系のデフォルトです。 + + diff --git a/indra/newview/skins/default/xui/pl/control_table_contents_camera.xml b/indra/newview/skins/default/xui/pl/control_table_contents_camera.xml new file mode 100644 index 0000000000..95a2e0acee --- /dev/null +++ b/indra/newview/skins/default/xui/pl/control_table_contents_camera.xml @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/indra/newview/skins/default/xui/pl/control_table_contents_columns_basic.xml b/indra/newview/skins/default/xui/pl/control_table_contents_columns_basic.xml new file mode 100644 index 0000000000..5f995b4128 --- /dev/null +++ b/indra/newview/skins/default/xui/pl/control_table_contents_columns_basic.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/indra/newview/skins/default/xui/pl/control_table_contents_editing.xml b/indra/newview/skins/default/xui/pl/control_table_contents_editing.xml new file mode 100644 index 0000000000..568b7dcf6d --- /dev/null +++ b/indra/newview/skins/default/xui/pl/control_table_contents_editing.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/indra/newview/skins/default/xui/pl/control_table_contents_media.xml b/indra/newview/skins/default/xui/pl/control_table_contents_media.xml new file mode 100644 index 0000000000..7346b83574 --- /dev/null +++ b/indra/newview/skins/default/xui/pl/control_table_contents_media.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/indra/newview/skins/default/xui/pl/control_table_contents_movement.xml b/indra/newview/skins/default/xui/pl/control_table_contents_movement.xml new file mode 100644 index 0000000000..93dd24f0d5 --- /dev/null +++ b/indra/newview/skins/default/xui/pl/control_table_contents_movement.xml @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/indra/newview/skins/default/xui/pl/floater_buy_object.xml b/indra/newview/skins/default/xui/pl/floater_buy_object.xml index 641ae07e8b..a94cadf10e 100644 --- a/indra/newview/skins/default/xui/pl/floater_buy_object.xml +++ b/indra/newview/skins/default/xui/pl/floater_buy_object.xml @@ -15,6 +15,9 @@ (bez prawa transferu) + + Wiele wybranych + i jej zawartość: diff --git a/indra/newview/skins/default/xui/pl/floater_preferences.xml b/indra/newview/skins/default/xui/pl/floater_preferences.xml index 07a300b234..b2fc905312 100644 --- a/indra/newview/skins/default/xui/pl/floater_preferences.xml +++ b/indra/newview/skins/default/xui/pl/floater_preferences.xml @@ -19,6 +19,7 @@ https://accounts.secondlife.com/change_email/ + diff --git a/indra/newview/skins/default/xui/pl/floater_preview_animation.xml b/indra/newview/skins/default/xui/pl/floater_preview_animation.xml index 9c58386441..23bc933f2d 100644 --- a/indra/newview/skins/default/xui/pl/floater_preview_animation.xml +++ b/indra/newview/skins/default/xui/pl/floater_preview_animation.xml @@ -8,4 +8,14 @@