diff --git a/.github/workflows/build_viewer.yml b/.github/workflows/build_viewer.yml index 8bc2ae7010..f56452fb47 100644 --- a/.github/workflows/build_viewer.yml +++ b/.github/workflows/build_viewer.yml @@ -2,84 +2,181 @@ name: Build viewer on: push env: AUTOBUILD_VARIABLES_FILE: ${{github.workspace}}/build-variables/variables - EXTRA_ARGS: -DFMODSTUDIO=Off -DUSE_KDU=Off + EXTRA_ARGS: -DFMODSTUDIO=ON -DUSE_KDU=ON --crashreporting + build_secrets_checkout: ${{github.workspace}}/signing + jobs: build_matrix: strategy: matrix: - os: [macos-11,ubuntu-18.04,windows-2022] + os: [macos-10.15,ubuntu-18.04,windows-2022] grid: [sl,os] addrsize: [64,32] exclude: - os: ubuntu-18.04 addrsize: 32 - - os: macos-11 + - os: macos-10.15 addrsize: 32 runs-on: ${{ matrix.os }} steps: - - name: Set OS flag - if: matrix.grid == 'os' - run: echo "FS_GRID=-DOPENSIM:BOOL=ON" >> $GITHUB_ENV - shell: bash + - uses: actions/checkout@v3 + - uses: actions/setup-python@v4 + if: runner.os != 'Windows' + id: py311 + with: + python-version: '3.11' + cache: 'pip' + - run: pip3 install -r requirements.txt + - name: Check python version + run: python -V + - name: Checkout build var + uses: actions/checkout@v3 + with: + repository: FirestormViewer/fs-build-variables + path: build-variables + - name: Setup rclone and download the folder + uses: beqjanus/setup-rclone@main + with: + rclone_config: ${{ secrets.RCLONE_CONFIG }} - - name: Set SL flag - if: matrix.grid == 'sl' - run: echo "FS_GRID=-DOPENSIM:BOOL=OFF" >> $GITHUB_ENV - shell: bash - - - name: Get the code - uses: actions/checkout@v3 - with: - fetch-depth: 1 + - name: Set OS flag + if: matrix.grid == 'os' + run: echo "FS_GRID=-DOPENSIM:BOOL=ON" >> $GITHUB_ENV + shell: bash - - name: Checkout build var - uses: actions/checkout@v3 - with: - repository: FirestormViewer/fs-build-variables - path: build-variables + - name: Set channel name + if: matrix.addrsize == '64' + run: echo "FS_RELEASE_CHAN=Releasex64" >> $GITHUB_ENV + shell: bash + + - name: Set channel name for 32 bit + if: matrix.addrsize == '32' + run: echo "FS_RELEASE_CHAN=Release" >> $GITHUB_ENV + shell: bash + + - name: Set SL flag + if: matrix.grid == 'sl' + run: echo "FS_GRID=-DOPENSIM:BOOL=OFF -DHAVOK_TPV:BOOL=ON" >> $GITHUB_ENV + shell: bash - - name: set VSVER for Windows builds - if: runner.os == 'Windows' - run: echo "AUTOBUILD_VSVER=170" >> $GITHUB_ENV - shell: bash + - name: Get the code + uses: actions/checkout@v3 + with: + fetch-depth: 0 - - name: Install required Ubuntu packages - if: runner.os == 'Linux' - run: sudo apt-get install python3-setuptools mesa-common-dev libgl1-mesa-dev libxinerama-dev libxrandr-dev libpulse-dev libglu1-mesa-dev + - name: Checkout build var + uses: actions/checkout@v3 + with: + repository: FirestormViewer/fs-build-variables + path: build-variables - - name: install autobuild - run: pip3 install git+https://github.com/Nicky-D/autobuild@main_nd + - name: rclone the private 3p packages on Windows + if: runner.os == 'Windows' + run: 'rclone copy fs_bundles: --include "*windows*bz2" .' + - name: rclone the private 3p packages on MacOS + if: runner.os == 'MacOS' + run: 'rclone copy fs_bundles: --include "*darwin*bz2" .' + - name: rclone the private 3p packages on Linux + if: runner.os == 'Linux' + run: 'rclone copy fs_bundles: --include "*linux*bz2" .' - - name: install autobuild - run: pip3 install llbase + - name: set VSVER for Windows builds + if: runner.os == 'Windows' + run: echo "AUTOBUILD_VSVER=170" >> $GITHUB_ENV + shell: bash + - name: Install certificate + if: runner.os == 'macOS' + env: + FS_CERT: ${{ secrets.FS_CERT }} + FS_CERT_PASS: ${{ secrets.FS_CERT_PASS }} + FS_KEYCHAIN_PASS: ${{ secrets.FS_KEYCHAIN_PASS }} + NOTARIZE_CREDS: ${{ secrets.NOTARIZE_CREDS }} + run: | + mkdir -p ${build_secrets_checkout}/code-signing-osx + echo -n "$FS_CERT" | base64 --decode --output ${build_secrets_checkout}/code-signing-osx/fs-cert.p12 + echo -n "$FS_CERT_PASS" >${build_secrets_checkout}/code-signing-osx/password.txt + echo -n "$NOTARIZE_CREDS" | base64 --decode --output ${build_secrets_checkout}/code-signing-osx/notarize_creds.sh + security create-keychain -p "$FS_KEYCHAIN_PASS" ~/Library/Keychains/viewer.keychain + security set-keychain-settings -lut 21600 ~/Library/Keychains/viewer.keychain + security unlock-keychain -p "$FS_KEYCHAIN_PASS" ~/Library/Keychains/viewer.keychain + security import ${build_secrets_checkout}/code-signing-osx/fs-cert.p12 -P "$FS_CERT_PASS" -A -t cert -f pkcs12 -k ~/Library/Keychains/viewer.keychain + security set-key-partition-list -S apple-tool:,apple:, -s -k "$FS_KEYCHAIN_PASS" -t private ~/Library/Keychains/viewer.keychain + security list-keychain -d user -s ~/Library/Keychains/viewer.keychain + - name: Install required Ubuntu packages + if: runner.os == 'Linux' + run: sudo apt-get install python3-setuptools mesa-common-dev libgl1-mesa-dev libxinerama-dev libxrandr-dev libpulse-dev libglu1-mesa-dev + - name: install autobuild + run: pip3 install git+https://github.com/Nicky-D/autobuild@main_nd - - name: Configure - run: autobuild configure -c ReleaseFS -A${{matrix.addrsize}} -- --package --chan ${{github.ref_name}} ${{env.EXTRA_ARGS}} ${{env.FS_GRID}} - shell: bash - - - name: build - run: autobuild build -c ReleaseFS -A${{matrix.addrsize}} --no-configure - shell: bash + - name: install autobuild + run: pip3 install llbase - - name: publish ${{ matrix.os }} artifacts - if: runner.os == 'Windows' - uses: actions/upload-artifact@v3 - with: - name: ${{ matrix.os }}-${{matrix.addrsize}}-${{matrix.grid}}-artifacts.zip - path: | - build-*/newview/Release/*Setup.exe - build-*/newview/Release/*.xz + - name: edit installables (64 bit) + if: runner.os == 'Windows' && matrix.addrsize == 64 + run: | + autobuild installables edit llphysicsextensions_tpv platform=windows${{matrix.addrsize}} url='file:///\${{ github.workspace }}\llphysicsextensions_tpv-1.0.571939-windows${{matrix.addrsize}}-571939.tar.bz2' + autobuild installables edit fmodstudio platform=windows${{matrix.addrsize}} url='file:///\${{ github.workspace }}\fmodstudio-2.02.09-windows${{matrix.addrsize}}-222890941.tar.bz2' + shell: bash - - name: publish ${{ matrix.os }} artifacts - if: runner.os == 'Linux' - uses: actions/upload-artifact@v3 - with: - name: ${{ matrix.os }}-${{matrix.addrsize}}-${{matrix.grid}}-artifacts.zip - path: build-linux-*/newview/*.xz + - name: edit installables (32 bit) + if: runner.os == 'Windows' && matrix.addrsize == 32 + run: | + autobuild installables edit llphysicsextensions_tpv platform=windows url='file:///\${{ github.workspace }}\llphysicsextensions_tpv-1.0.571939-windows-571939.tar.bz2' + autobuild installables edit fmodstudio platform=windows url='file:///\${{ github.workspace }}\fmodstudio-2.02.09-windows-222890940.tar.bz2' + shell: bash - - name: publish ${{ matrix.os }} artifacts - if: runner.os == 'macOS' - uses: actions/upload-artifact@v3 - with: - name: ${{ matrix.os }}-${{matrix.addrsize}}-${{matrix.grid}}-artifacts.zip - path: build-darwin-*/newview/*.dmg + - name: edit installables (32/64 agnostic) + if: runner.os == 'Windows' + run: | + autobuild installables edit kdu platform=windows url='file:///\${{ github.workspace }}\kdu-8.2-windows-212351246.tar.bz2' + shell: bash + + - name: edit installables + if: runner.os == 'macOS' + run: | + autobuild installables edit llphysicsextensions_tpv platform=darwin${{matrix.addrsize}} url='file:////${{ github.workspace }}/llphysicsextensions_tpv-1.0.571939-darwin${{matrix.addrsize}}-571939.tar.bz2' + autobuild installables edit kdu platform=darwin url='file:////${{ github.workspace }}/kdu-8.2-darwin-212431232.tar.bz2' + autobuild installables --debug edit fmodstudio platform=darwin${{matrix.addrsize}} url='file:////${{ github.workspace }}/fmodstudio-2.02.09-darwin${{matrix.addrsize}}-5.tar.bz2' + shell: bash + + - name: edit installables + if: runner.os == 'Linux' + run: | + autobuild installables edit kdu platform=linux${{matrix.addrsize}} url='file:////${{ github.workspace }}/kdu-8.2-linux${{matrix.addrsize}}_bionic-220911445.tar.bz2' + autobuild installables edit fmodstudio platform=linux${{matrix.addrsize}} url='file:////${{ github.workspace }}/fmodstudio-2.02.09-linux${{matrix.addrsize}}-222891103.tar.bz2' + shell: bash + + - name: Configure + run: autobuild configure --debug -c ReleaseFS -A${{matrix.addrsize}} -- --package --chan ${{env.FS_RELEASE_CHAN}} ${{env.EXTRA_ARGS}} ${{env.FS_GRID}} + shell: bash + + - name: build + run: autobuild build --debug -c ReleaseFS -A${{matrix.addrsize}} --no-configure + shell: bash + + - name: publish Windows artifacts + if: runner.os == 'Windows' + uses: actions/upload-artifact@v3 + with: + name: ${{ matrix.os }}-${{matrix.addrsize}}-${{matrix.grid}}-artifacts.zip + path: | + build-*/newview/Release/*Setup.exe + build-*/newview/Release/*.xz + + - name: publish Linux artifacts + if: runner.os == 'Linux' + uses: actions/upload-artifact@v3 + with: + name: ${{ matrix.os }}-${{matrix.addrsize}}-${{matrix.grid}}-artifacts.zip + path: | + build-linux-*/newview/*.xz + build-linux-*/newview/*.bz2 + + - name: publish MacOS artifacts + if: runner.os == 'macOS' + uses: actions/upload-artifact@v3 + with: + name: ${{ matrix.os }}-${{matrix.addrsize}}-${{matrix.grid}}-artifacts.zip + path: | + build-darwin-*/newview/*.dmg + build-darwin-*/newview/*.bz2 diff --git a/autobuild.xml b/autobuild.xml index 13dd558770..e737e69b74 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -672,9 +672,9 @@ archive hash - ae90d19cdcddf539f6d0b41cab12f918 + 7b4aceaed511d44c4d1354b2162b59c7 url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/72773/702861/bugsplat-1.0.7.552580-darwin64-552580.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/107398/936936/bugsplat-1.0.7.576560-darwin64-576560.tar.bz2 name darwin64 @@ -684,9 +684,9 @@ archive hash - f5936eceb6a33ff0f1cc31996a40f29c + 53918c7c74b943cdc0bb90caf9657a84 url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/72774/702905/bugsplat-3.6.0.8.552580-windows-552580.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/107400/936949/bugsplat-4.0.3.0.576560-windows-576560.tar.bz2 name windows @@ -696,16 +696,16 @@ archive hash - 9cd940754e53e0670030b3da5ba8f373 + 19d6a55db101f02e7eb531daf3e8cfd1 url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/72775/702906/bugsplat-3.6.0.8.552580-windows64-552580.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/107401/936948/bugsplat-.576560-windows64-576560.tar.bz2 name windows64 version - 3.6.0.8.552580 + 4.0.3.0.576560 colladadom @@ -3216,9 +3216,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - 1dda5fb3bb649b0ab5a93f22df7cb11e + 2e8d817e7837dd6f4284b13fa3f5c15e url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/96998/862110/viewer_manager-3.0.569958-darwin64-569958.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/104765/917714/viewer_manager-3.0.575083-darwin64-575083.tar.bz2 name darwin64 @@ -3240,9 +3240,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - 30d1386d0a6883d898fc56757a789b8b + 3efa80faaf537e39a77218cd6efa9409 url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/97002/862130/viewer_manager-3.0.569958-windows-569958.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/104766/917721/viewer_manager-3.0.575083-windows-575083.tar.bz2 name windows @@ -3253,7 +3253,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors source_type hg version - 3.0.569958 + 3.0.575083 vlc-bin diff --git a/doc/contributions.txt b/doc/contributions.txt index 56e3f8ba4f..6438c178a8 100755 --- a/doc/contributions.txt +++ b/doc/contributions.txt @@ -285,6 +285,7 @@ Beq Janus SL-15709 SL-16021 SL-16027 + SL-18637 Beth Walcher Bezilon Kasei Biancaluce Robbiani diff --git a/indra/llaudio/llstreamingaudio.h b/indra/llaudio/llstreamingaudio.h index aa3fbe93e5..5e4c639f05 100644 --- a/indra/llaudio/llstreamingaudio.h +++ b/indra/llaudio/llstreamingaudio.h @@ -29,6 +29,7 @@ #define LL_STREAMINGAUDIO_H #include "stdtypes.h" // from llcommon +#include // Entirely abstract. Based exactly on the historic API. class LLStreamingAudioInterface @@ -49,7 +50,15 @@ class LLStreamingAudioInterface virtual void setBufferSizes(U32 streambuffertime, U32 decodebuffertime){}; // These three are Firestorm additions and thus optional. - virtual bool getNewMetadata(LLSD& metadata) { return false; } + using metadata_update_callback_t = boost::signals2::signal; + virtual boost::signals2::connection setMetadataUpdateCallback(const metadata_update_callback_t::slot_type& cb) noexcept + { + return mMetadataUpdateSignal.connect(cb); + } + virtual LLSD getCurrentMetadata() const noexcept { return LLSD(); } + +protected: + metadata_update_callback_t mMetadataUpdateSignal; }; #endif // LL_STREAMINGAUDIO_H diff --git a/indra/llaudio/llstreamingaudio_fmodstudio.cpp b/indra/llaudio/llstreamingaudio_fmodstudio.cpp index c73b1f8958..3b7b338662 100644 --- a/indra/llaudio/llstreamingaudio_fmodstudio.cpp +++ b/indra/llaudio/llstreamingaudio_fmodstudio.cpp @@ -199,15 +199,14 @@ void LLStreamingAudio_FMODSTUDIO::update() if (!Check_FMOD_Error(mFMODInternetStreamChannelp->getCurrentSound(&sound), "FMOD::Channel::getCurrentSound") && sound) { FMOD_TAG tag; - S32 tagcount, dirtytagcount; + S32 tagcount, numtagsupdated; - if (!Check_FMOD_Error(sound->getNumTags(&tagcount, &dirtytagcount), "FMOD::Sound::getNumTags") && dirtytagcount) + if (!Check_FMOD_Error(sound->getNumTags(&tagcount, &numtagsupdated), "FMOD::Sound::getNumTags") && numtagsupdated > 0) { - LL_DEBUGS("StreamMetadata") << "Tag count: " << tagcount << " Dirty tag count: " << dirtytagcount << LL_ENDL; + LL_DEBUGS("StreamMetadata") << "Tag count: " << tagcount << " Tags updated since last call: " << numtagsupdated << LL_ENDL; // Stream metadata - originally by Shyotl Khur mMetadata.clear(); - mNewMetadata = true; // for (S32 i = 0; i < tagcount; ++i) { @@ -298,6 +297,8 @@ void LLStreamingAudio_FMODSTUDIO::update() break; } } + + mMetadataUpdateSignal(mMetadata); } if (starving) @@ -329,6 +330,11 @@ void LLStreamingAudio_FMODSTUDIO::stop() Check_FMOD_Error(mFMODInternetStreamChannelp->setPaused(true), "FMOD::Channel::setPaused"); Check_FMOD_Error(mFMODInternetStreamChannelp->setPriority(0), "FMOD::Channel::setPriority"); mFMODInternetStreamChannelp = NULL; + + // Stream meta data display + mMetadata.clear(); + mMetadataUpdateSignal(mMetadata); + // } if (mCurrentInternetStreamp) @@ -411,29 +417,6 @@ void LLStreamingAudio_FMODSTUDIO::setGain(F32 vol) } } -// Streamtitle display -// virtual -bool LLStreamingAudio_FMODSTUDIO::getNewMetadata(LLSD& metadata) -{ - if (mCurrentInternetStreamp) - { - if (mNewMetadata) - { - metadata = mMetadata; - mNewMetadata = false; - return true; - } - else - { - return false; - } - } - - metadata = LLSD(); - return false; -} -// - /////////////////////////////////////////////////////// // manager of possibly-multiple internet audio streams diff --git a/indra/llaudio/llstreamingaudio_fmodstudio.h b/indra/llaudio/llstreamingaudio_fmodstudio.h index 43e8ef9c81..13501c2710 100644 --- a/indra/llaudio/llstreamingaudio_fmodstudio.h +++ b/indra/llaudio/llstreamingaudio_fmodstudio.h @@ -61,8 +61,8 @@ public: /*virtual*/ bool supportsAdjustableBufferSizes(){return true;} /*virtual*/ void setBufferSizes(U32 streambuffertime, U32 decodebuffertime); //Streamtitle display DKO - virtual bool getNewMetadata(LLSD& metadata); - // DKO + LLSD getCurrentMetadata() const noexcept { return mMetadata; } + private: bool releaseDeadStreams(); @@ -77,12 +77,9 @@ private: std::string mPendingURL; F32 mGain; // Streamtitle display - bool mNewMetadata; LLSD mMetadata; - // Streamtitle display bool mWasAlreadyPlaying; }; - #endif // LL_STREAMINGAUDIO_FMODSTUDIO_H diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index cee4b6b555..682f7c997e 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -95,7 +95,6 @@ set(llcommon_SOURCE_FILES llsys.cpp lltempredirect.cpp llthread.cpp - llthreadlocalstorage.cpp llthreadsafequeue.cpp lltimer.cpp lltrace.cpp diff --git a/indra/llcommon/llapr.cpp b/indra/llcommon/llapr.cpp index 4413d89186..7b2197dac1 100644 --- a/indra/llcommon/llapr.cpp +++ b/indra/llcommon/llapr.cpp @@ -30,7 +30,6 @@ #include "llapr.h" #include "llmutex.h" #include "apr_dso.h" -#include "llthreadlocalstorage.h" apr_pool_t *gAPRPoolp = NULL; // Global APR memory pool LLVolatileAPRPool *LLAPRFile::sAPRFilePoolp = NULL ; //global volatile APR memory pool. @@ -54,7 +53,6 @@ void ll_init_apr() LLAPRFile::sAPRFilePoolp = new LLVolatileAPRPool(FALSE) ; } - LLThreadLocalPointerBase::initAllThreadLocalStorage(); gAPRInitialized = true; } @@ -70,8 +68,6 @@ void ll_cleanup_apr() LL_DEBUGS("APR") << "Cleaning up APR" << LL_ENDL; - LLThreadLocalPointerBase::destroyAllThreadLocalStorage(); - if (gAPRPoolp) { apr_pool_destroy(gAPRPoolp); diff --git a/indra/llcommon/llthreadlocalstorage.cpp b/indra/llcommon/llthreadlocalstorage.cpp deleted file mode 100644 index d8a063e8d5..0000000000 --- a/indra/llcommon/llthreadlocalstorage.cpp +++ /dev/null @@ -1,115 +0,0 @@ -/** - * @file llthreadlocalstorage.cpp - * @author Richard - * @date 2013-1-11 - * @brief implementation of thread local storage utility classes - * - * $LicenseInfo:firstyear=2013&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#include "linden_common.h" -#include "llthreadlocalstorage.h" -#include "llapr.h" - -// -//LLThreadLocalPointerBase -// -bool LLThreadLocalPointerBase::sInitialized = false; - -void LLThreadLocalPointerBase::set( void* value ) -{ - llassert(sInitialized && mThreadKey); - - apr_status_t result = apr_threadkey_private_set((void*)value, mThreadKey); - if (result != APR_SUCCESS) - { - ll_apr_warn_status(result); - LL_ERRS() << "Failed to set thread local data" << LL_ENDL; - } -} - -void* LLThreadLocalPointerBase::get() const -{ - // llassert(sInitialized); - void* ptr; - apr_status_t result = - apr_threadkey_private_get(&ptr, mThreadKey); - if (result != APR_SUCCESS) - { - ll_apr_warn_status(result); - LL_ERRS() << "Failed to get thread local data" << LL_ENDL; - } - return ptr; -} - - -void LLThreadLocalPointerBase::initStorage( ) -{ - apr_status_t result = apr_threadkey_private_create(&mThreadKey, NULL, gAPRPoolp); - if (result != APR_SUCCESS) - { - ll_apr_warn_status(result); - LL_ERRS() << "Failed to allocate thread local data" << LL_ENDL; - } -} - -void LLThreadLocalPointerBase::destroyStorage() -{ - if (sInitialized) - { - if (mThreadKey) - { - apr_status_t result = apr_threadkey_private_delete(mThreadKey); - if (result != APR_SUCCESS) - { - ll_apr_warn_status(result); - LL_ERRS() << "Failed to delete thread local data" << LL_ENDL; - } - } - } -} - -//static -void LLThreadLocalPointerBase::initAllThreadLocalStorage() -{ - if (!sInitialized) - { - for (auto& base : instance_snapshot()) - { - base.initStorage(); - } - sInitialized = true; - } -} - -//static -void LLThreadLocalPointerBase::destroyAllThreadLocalStorage() -{ - if (sInitialized) - { - //for (auto& base : instance_snapshot()) - //{ - // base.destroyStorage(); - //} - sInitialized = false; - } -} diff --git a/indra/llcommon/llthreadlocalstorage.h b/indra/llcommon/llthreadlocalstorage.h index 3b5786023f..bdd28ec865 100644 --- a/indra/llcommon/llthreadlocalstorage.h +++ b/indra/llcommon/llthreadlocalstorage.h @@ -30,100 +30,6 @@ #include "llinstancetracker.h" -class LLThreadLocalPointerBase : public LLInstanceTracker -{ -public: - LLThreadLocalPointerBase() - : mThreadKey(NULL) - { - if (sInitialized) - { - initStorage(); - } - } - - LLThreadLocalPointerBase( const LLThreadLocalPointerBase& other) - : mThreadKey(NULL) - { - if (sInitialized) - { - initStorage(); - } - } - - ~LLThreadLocalPointerBase() - { - destroyStorage(); - } - - static void initAllThreadLocalStorage(); - static void destroyAllThreadLocalStorage(); - -protected: - void set(void* value); - - void* get() const; - - void initStorage(); - void destroyStorage(); - -protected: - struct apr_threadkey_t* mThreadKey; - static bool sInitialized; -}; - -template -class LLThreadLocalPointer : public LLThreadLocalPointerBase -{ -public: - - LLThreadLocalPointer() - {} - - explicit LLThreadLocalPointer(T* value) - { - set(value); - } - - - LLThreadLocalPointer(const LLThreadLocalPointer& other) - : LLThreadLocalPointerBase(other) - { - set(other.get()); - } - - LL_FORCE_INLINE T* get() const - { - return (T*)LLThreadLocalPointerBase::get(); - } - - T* operator -> () const - { - return (T*)get(); - } - - T& operator*() const - { - return *(T*)get(); - } - - LLThreadLocalPointer& operator = (T* value) - { - set((void*)value); - return *this; - } - - bool operator ==(const T* other) const - { - if (!sInitialized) return false; - return get() == other; - } - - bool isNull() const { return !sInitialized || get() == NULL; } - - bool notNull() const { return sInitialized && get() != NULL; } -}; - template class LLThreadLocalSingletonPointer { @@ -139,10 +45,10 @@ public: } private: - static LL_THREAD_LOCAL DERIVED_TYPE* sInstance; + static thread_local DERIVED_TYPE* sInstance; }; template -LL_THREAD_LOCAL DERIVED_TYPE* LLThreadLocalSingletonPointer::sInstance = NULL; +thread_local DERIVED_TYPE* LLThreadLocalSingletonPointer::sInstance = NULL; #endif // LL_LLTHREADLOCALSTORAGE_H diff --git a/indra/llcommon/lltrace.cpp b/indra/llcommon/lltrace.cpp index f59b207ded..acdda5fe1e 100644 --- a/indra/llcommon/lltrace.cpp +++ b/indra/llcommon/lltrace.cpp @@ -40,7 +40,7 @@ StatBase::StatBase( const char* name, const char* description ) mDescription(description ? description : "") { #ifndef LL_RELEASE_FOR_DOWNLOAD - if (LLTrace::get_thread_recorder().notNull()) + if (LLTrace::get_thread_recorder() != NULL) { LL_ERRS() << "Attempting to declare trace object after program initialization. Trace objects should be statically initialized." << LL_ENDL; } diff --git a/indra/llcommon/lltraceaccumulators.cpp b/indra/llcommon/lltraceaccumulators.cpp index 34299f5a29..fe447d5319 100644 --- a/indra/llcommon/lltraceaccumulators.cpp +++ b/indra/llcommon/lltraceaccumulators.cpp @@ -93,7 +93,7 @@ void AccumulatorBufferGroup::makeCurrent() mStackTimers.makeCurrent(); mMemStats.makeCurrent(); - ThreadRecorder* thread_recorder = get_thread_recorder().get(); + ThreadRecorder* thread_recorder = get_thread_recorder(); AccumulatorBuffer& timer_accumulator_buffer = mStackTimers; // update stacktimer parent pointers for (S32 i = 0, end_i = mStackTimers.size(); i < end_i; i++) diff --git a/indra/llcommon/lltracerecording.cpp b/indra/llcommon/lltracerecording.cpp index 1613af1dcf..8cbb0db135 100644 --- a/indra/llcommon/lltracerecording.cpp +++ b/indra/llcommon/lltracerecording.cpp @@ -95,7 +95,7 @@ Recording::~Recording() // allow recording destruction without thread recorder running, // otherwise thread shutdown could crash if a recording outlives the thread recorder // besides, recording construction and destruction is fine without a recorder...just don't attempt to start one - if (isStarted() && LLTrace::get_thread_recorder().notNull()) + if (isStarted() && LLTrace::get_thread_recorder() != NULL) { LLTrace::get_thread_recorder()->deactivate(mBuffers.write()); } @@ -112,9 +112,9 @@ void Recording::update() // must have llassert(mActiveBuffers != NULL - && LLTrace::get_thread_recorder().notNull()); + && LLTrace::get_thread_recorder() != NULL); - if(!mActiveBuffers->isCurrent()) + if(!mActiveBuffers->isCurrent() && LLTrace::get_thread_recorder() != NULL) { AccumulatorBufferGroup* buffers = mBuffers.write(); LLTrace::get_thread_recorder()->deactivate(buffers); @@ -144,7 +144,7 @@ void Recording::handleStart() mSamplingTimer.reset(); mBuffers.setStayUnique(true); // must have thread recorder running on this thread - llassert(LLTrace::get_thread_recorder().notNull()); + llassert(LLTrace::get_thread_recorder() != NULL); mActiveBuffers = LLTrace::get_thread_recorder()->activate(mBuffers.write()); #endif } @@ -155,7 +155,7 @@ void Recording::handleStop() #if LL_TRACE_ENABLED mElapsedSeconds += mSamplingTimer.getElapsedTimeF64(); // must have thread recorder running on this thread - llassert(LLTrace::get_thread_recorder().notNull()); + llassert(LLTrace::get_thread_recorder() != NULL); LLTrace::get_thread_recorder()->deactivate(mBuffers.write()); mActiveBuffers = NULL; mBuffers.setStayUnique(false); @@ -1181,8 +1181,8 @@ void ExtendablePeriodicRecording::handleSplitTo(ExtendablePeriodicRecording& oth PeriodicRecording& get_frame_recording() { - static LLThreadLocalPointer sRecording(new PeriodicRecording(200, PeriodicRecording::STARTED)); - return *sRecording; + static thread_local PeriodicRecording sRecording(200, PeriodicRecording::STARTED); + return sRecording; } } diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp index 090d3297a0..26db15eaa0 100644 --- a/indra/llcommon/lltracethreadrecorder.cpp +++ b/indra/llcommon/lltracethreadrecorder.cpp @@ -308,13 +308,13 @@ ThreadRecorder* get_master_thread_recorder() return sMasterThreadRecorder; } -LLThreadLocalPointer& get_thread_recorder_ptr() +ThreadRecorder*& get_thread_recorder_ptr() { - static LLThreadLocalPointer s_thread_recorder; + static thread_local ThreadRecorder* s_thread_recorder; return s_thread_recorder; } -const LLThreadLocalPointer& get_thread_recorder() +ThreadRecorder* get_thread_recorder() { return get_thread_recorder_ptr(); } diff --git a/indra/llcommon/lltracethreadrecorder.h b/indra/llcommon/lltracethreadrecorder.h index a797c6687e..8fd1e5ef58 100644 --- a/indra/llcommon/lltracethreadrecorder.h +++ b/indra/llcommon/lltracethreadrecorder.h @@ -32,7 +32,6 @@ #include "llmutex.h" #include "lltraceaccumulators.h" -#include "llthreadlocalstorage.h" namespace LLTrace { @@ -92,7 +91,7 @@ namespace LLTrace }; - const LLThreadLocalPointer& get_thread_recorder(); + ThreadRecorder* get_thread_recorder(); void set_thread_recorder(ThreadRecorder*); void set_master_thread_recorder(ThreadRecorder*); diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 2b192b45de..8fe14a5910 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -5082,6 +5082,17 @@ void LLVolumeFace::optimize(F32 angle_cutoff) { U16 index = mIndices[i]; + if (index >= mNumVertices) + { + // invalid index + // replace with a valid index to avoid crashes + index = mNumVertices - 1; + mIndices[i] = index; + + // Needs better logging + LL_DEBUGS_ONCE("LLVOLUME") << "Invalid index, substituting" << LL_ENDL; + } + LLVolumeFace::VertexData cv; getVertexData(index, cv); @@ -5462,6 +5473,17 @@ bool LLVolumeFace::cacheOptimize() U16 idx = mIndices[i]; U32 tri_idx = i / 3; + if (idx >= mNumVertices) + { + // invalid index + // replace with a valid index to avoid crashes + idx = mNumVertices - 1; + mIndices[i] = idx; + + // Needs better logging + LL_DEBUGS_ONCE("LLVOLUME") << "Invalid index, substituting" << LL_ENDL; + } + vertex_data[idx].mTriangles.push_back(&(triangle_data[tri_idx])); vertex_data[idx].mIdx = idx; triangle_data[tri_idx].mVertex[i % 3] = &(vertex_data[idx]); diff --git a/indra/llmessage/message_prehash.cpp b/indra/llmessage/message_prehash.cpp index b00d3ff6b2..1fb99dd407 100644 --- a/indra/llmessage/message_prehash.cpp +++ b/indra/llmessage/message_prehash.cpp @@ -666,7 +666,7 @@ char const* const _PREHASH_GroupRolesCount = LLMessageStringTable::getInstance() char const* const _PREHASH_SimulatorBlock = LLMessageStringTable::getInstance()->getString("SimulatorBlock"); char const* const _PREHASH_GroupID = LLMessageStringTable::getInstance()->getString("GroupID"); char const* const _PREHASH_AgentVel = LLMessageStringTable::getInstance()->getString("AgentVel"); -char const* const _PREHASH_RequestImage = LLMessageStringTable::getInstance()->getString("RequestImage"); +char const* const _PREHASH_RequestImage = LLMessageStringTable::getInstance()->getString("RequestImage"); // OpenSim compatibility char const* const _PREHASH_NetStats = LLMessageStringTable::getInstance()->getString("NetStats"); char const* const _PREHASH_AgentPos = LLMessageStringTable::getInstance()->getString("AgentPos"); char const* const _PREHASH_AgentSit = LLMessageStringTable::getInstance()->getString("AgentSit"); @@ -1047,7 +1047,7 @@ char const* const _PREHASH_SortOrder = LLMessageStringTable::getInstance()->getS char const* const _PREHASH_Hunter = LLMessageStringTable::getInstance()->getString("Hunter"); char const* const _PREHASH_SunAngVelocity = LLMessageStringTable::getInstance()->getString("SunAngVelocity"); char const* const _PREHASH_BinaryBucket = LLMessageStringTable::getInstance()->getString("BinaryBucket"); -char const* const _PREHASH_ImagePacket = LLMessageStringTable::getInstance()->getString("ImagePacket"); +char const* const _PREHASH_ImagePacket = LLMessageStringTable::getInstance()->getString("ImagePacket"); // OpenSim compatibility char const* const _PREHASH_StartGroupProposal = LLMessageStringTable::getInstance()->getString("StartGroupProposal"); char const* const _PREHASH_EnergyLevel = LLMessageStringTable::getInstance()->getString("EnergyLevel"); char const* const _PREHASH_PriceForListing = LLMessageStringTable::getInstance()->getString("PriceForListing"); @@ -1236,7 +1236,7 @@ char const* const _PREHASH_ForceScriptControlRelease = LLMessageStringTable::get char const* const _PREHASH_ParcelRelease = LLMessageStringTable::getInstance()->getString("ParcelRelease"); char const* const _PREHASH_VFileType = LLMessageStringTable::getInstance()->getString("VFileType"); char const* const _PREHASH_EjectGroupMemberReply = LLMessageStringTable::getInstance()->getString("EjectGroupMemberReply"); -char const* const _PREHASH_ImageData = LLMessageStringTable::getInstance()->getString("ImageData"); +char const* const _PREHASH_ImageData = LLMessageStringTable::getInstance()->getString("ImageData"); // OpenSim compatibility char const* const _PREHASH_SimulatorViewerTimeMessage = LLMessageStringTable::getInstance()->getString("SimulatorViewerTimeMessage"); char const* const _PREHASH_Rotation = LLMessageStringTable::getInstance()->getString("Rotation"); char const* const _PREHASH_Selection = LLMessageStringTable::getInstance()->getString("Selection"); diff --git a/indra/llmessage/message_prehash.h b/indra/llmessage/message_prehash.h index e55972c0e1..c1112c2336 100644 --- a/indra/llmessage/message_prehash.h +++ b/indra/llmessage/message_prehash.h @@ -666,7 +666,7 @@ extern char const* const _PREHASH_GroupRolesCount; extern char const* const _PREHASH_SimulatorBlock; extern char const* const _PREHASH_GroupID; extern char const* const _PREHASH_AgentVel; -extern char const* const _PREHASH_RequestImage; +extern char const* const _PREHASH_RequestImage; // OpenSim compatibility extern char const* const _PREHASH_NetStats; extern char const* const _PREHASH_AgentPos; extern char const* const _PREHASH_AgentSit; @@ -1047,7 +1047,7 @@ extern char const* const _PREHASH_SortOrder; extern char const* const _PREHASH_Hunter; extern char const* const _PREHASH_SunAngVelocity; extern char const* const _PREHASH_BinaryBucket; -extern char const* const _PREHASH_ImagePacket; +extern char const* const _PREHASH_ImagePacket; // OpenSim compatibility extern char const* const _PREHASH_StartGroupProposal; extern char const* const _PREHASH_EnergyLevel; extern char const* const _PREHASH_PriceForListing; @@ -1236,7 +1236,7 @@ extern char const* const _PREHASH_ForceScriptControlRelease; extern char const* const _PREHASH_ParcelRelease; extern char const* const _PREHASH_VFileType; extern char const* const _PREHASH_EjectGroupMemberReply; -extern char const* const _PREHASH_ImageData; +extern char const* const _PREHASH_ImageData; // OpenSim compatibility extern char const* const _PREHASH_SimulatorViewerTimeMessage; extern char const* const _PREHASH_Rotation; extern char const* const _PREHASH_Selection; diff --git a/indra/llprimitive/lldaeloader.cpp b/indra/llprimitive/lldaeloader.cpp index 2ab09db340..9e7ead5188 100644 --- a/indra/llprimitive/lldaeloader.cpp +++ b/indra/llprimitive/lldaeloader.cpp @@ -377,7 +377,10 @@ LLModel::EModelStatus load_face_from_dom_triangles( // VFExtents change face.mExtents[0].set(v[0], v[1], v[2]); face.mExtents[1].set(v[0], v[1], v[2]); - point_map.clear(); + + verts.clear(); + indices.clear(); + point_map.clear(); } } diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp index 6d3b089d1f..b413005f88 100644 --- a/indra/llprimitive/llmodel.cpp +++ b/indra/llprimitive/llmodel.cpp @@ -845,7 +845,7 @@ LLSD LLModel::writeModel( mdl[model_names[idx]][i]["TriangleList"] = indices; - if (skinning) + if (skinning && idx != LLModel::LOD_PHYSICS) { //write out skin weights diff --git a/indra/llprimitive/llmodel.h b/indra/llprimitive/llmodel.h index 544aa3c5cb..7461a38ac9 100644 --- a/indra/llprimitive/llmodel.h +++ b/indra/llprimitive/llmodel.h @@ -62,6 +62,8 @@ public: mutable std::vector mJointNums; typedef std::vector> matrix_list_t; matrix_list_t mInvBindMatrix; + + // bones/joints position overrides matrix_list_t mAlternateBindMatrix; LL_ALIGN_16(LLMatrix4a mBindShapeMatrix); diff --git a/indra/llui/llchat.h b/indra/llui/llchat.h index 6f35eadeb5..89ded99f9d 100644 --- a/indra/llui/llchat.h +++ b/indra/llui/llchat.h @@ -38,7 +38,8 @@ typedef enum e_chat_source_type CHAT_SOURCE_AGENT = 1, CHAT_SOURCE_OBJECT = 2, CHAT_SOURCE_TELEPORT = 3, - CHAT_SOURCE_UNKNOWN = 4 + CHAT_SOURCE_UNKNOWN = 4, + CHAT_SOURCE_REGION = 5, } EChatSourceType; typedef enum e_chat_type diff --git a/indra/llui/llcheckboxctrl.cpp b/indra/llui/llcheckboxctrl.cpp index f2c6935c94..eed0d172db 100644 --- a/indra/llui/llcheckboxctrl.cpp +++ b/indra/llui/llcheckboxctrl.cpp @@ -213,11 +213,9 @@ void LLCheckBoxCtrl::reshape(S32 width, S32 height, BOOL called_from_parent) // 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 new_width = rect.getWidth() - label_rect.mLeft; + mLabel->reshape(new_width, label_rect.getHeight(), TRUE); S32 label_top = label_rect.mTop; mLabel->reshapeToFitText(TRUE); diff --git a/indra/llui/llfolderviewmodel.h b/indra/llui/llfolderviewmodel.h index f4173d661f..4b8a31a07e 100644 --- a/indra/llui/llfolderviewmodel.h +++ b/indra/llui/llfolderviewmodel.h @@ -173,7 +173,7 @@ public: virtual BOOL removeItem() = 0; virtual void removeBatch(std::vector& batch) = 0; - virtual BOOL isItemCopyable() const = 0; + virtual bool isItemCopyable(bool can_copy_as_link = true) const = 0; virtual BOOL copyToClipboard() const = 0; virtual BOOL cutToClipboard() = 0; virtual bool isCutToClipboard() { return false; }; diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index 7cd0157785..bc1aa24d25 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -3872,6 +3872,45 @@ boost::signals2::connection LLScrollListCtrl::setIsFriendCallback(const is_frien return mIsFriendSignal->connect(cb); } +bool LLScrollListCtrl::highlightMatchingItems(const std::string& filter_str) +{ + if (filter_str == "" || filter_str == " ") + { + clearHighlightedItems(); + return false; + } + + bool res = false; + + setHighlightedColor(LLUIColorTable::instance().getColor("SearchableControlHighlightColor", LLColor4::red)); + + std::string filter_str_lc(filter_str); + LLStringUtil::toLower(filter_str_lc); + + std::vector data = getAllData(); + std::vector::iterator iter = data.begin(); + while (iter != data.end()) + { + LLScrollListCell* cell = (*iter)->getColumn(0); + if (cell) + { + std::string value = cell->getValue().asString(); + LLStringUtil::toLower(value); + if (value.find(filter_str_lc) == std::string::npos) + { + (*iter)->setHighlighted(false); + } + else + { + (*iter)->setHighlighted(true); + res = true; + } + } + iter++; + } + return res; +} + // Fix for FS-specific people list (radar) void LLScrollListCtrl::setFilterString(const std::string& str) { diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h index 8b62ea735d..55d30ad422 100644 --- a/indra/llui/llscrolllistctrl.h +++ b/indra/llui/llscrolllistctrl.h @@ -444,6 +444,8 @@ public: void setNeedsSort(bool val = true) { mSorted = !val; mLastUpdateFrame = LLFrameTimer::getFrameCount(); } void dirtyColumns(); // some operation has potentially affected column layout or ordering + bool highlightMatchingItems(const std::string& filter_str); + boost::signals2::connection setSortCallback(sort_signal_t::slot_type cb ) { if (!mSortCallback) mSortCallback = new sort_signal_t(); diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index 0e8f9f2c5e..498dbc4a3a 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -385,63 +385,34 @@ void LLTextBase::onValueChange(S32 start, S32 end) { } -// Draws the black box behind the selected text -//void LLTextBase::drawSelectionBackground() // [SL:KB] - Patch: Control-TextHighlight | Checked: 2013-12-30 (Catznip-3.6) -void LLTextBase::drawSelectionBackground() -{ - if( hasSelection() && !mLineInfoList.empty()) - { - highlight_list_t highlights; - highlights.push_back(range_pair_t(llmin(mSelectionStart, mSelectionEnd), llmax(mSelectionStart, mSelectionEnd))); - drawHighlightsBackground(highlights, mSelectedBGColor); - } -} - void LLTextBase::drawHighlightsBackground(const highlight_list_t& highlights, const LLColor4& color) -// [SL:KB] - Patch: Control-TextHighlight | Checked: 2013-12-30 (Catznip-3.6) { -// // Draw selection even if we don't have keyboard focus for search/replace -// if( hasSelection() && !mLineInfoList.empty()) -// [SL:KB] - Patch: Control-TextHighlight | Checked: 2013-12-30 (Catznip-3.6) if (!mLineInfoList.empty()) -// [/SL:KB] { std::vector selection_rects; -// S32 selection_left = llmin( mSelectionStart, mSelectionEnd ); -// S32 selection_right = llmax( mSelectionStart, mSelectionEnd ); - // Skip through the lines we aren't drawing. LLRect content_display_rect = getVisibleDocumentRect(); // binary search for line that starts before top of visible buffer line_list_t::const_iterator line_iter = std::lower_bound(mLineInfoList.begin(), mLineInfoList.end(), content_display_rect.mTop, compare_bottom()); line_list_t::const_iterator end_iter = std::upper_bound(mLineInfoList.begin(), mLineInfoList.end(), content_display_rect.mBottom, compare_top()); - -// bool done = false; -// [SL:KB] - Patch: Control-TextHighlight | Checked: 2013-12-30 (Catznip-3.6) highlight_list_t::const_iterator itHighlight = highlights.begin(); -// [/SL:KB] // Find the coordinates of the selected area -// for (;line_iter != end_iter && !done; ++line_iter) -// [SL:KB] - Patch: Control-TextHighlight | Checked: 2013-12-30 (Catznip-3.6) for (; (line_iter != end_iter) && (itHighlight != highlights.end()); ++line_iter) -// [/SL:KB] { -// [SL:KB] - Patch: Control-TextHighlight | Checked: 2013-12-30 (Catznip-3.6) // Find a highlight range with an end index larger than the start of this line - while ( (itHighlight != highlights.end()) && (line_iter->mDocIndexStart > itHighlight->second) ) + while ((itHighlight != highlights.end()) && (line_iter->mDocIndexStart > itHighlight->second)) ++itHighlight; // Draw all highlights on the current line - while ( (itHighlight != highlights.end()) && (itHighlight->first < line_iter->mDocIndexEnd) ) + while ((itHighlight != highlights.end()) && (itHighlight->first < line_iter->mDocIndexEnd)) { // Keep the names of these to change fewer lines of LL code - S32 selection_left = llmin(itHighlight->first, itHighlight->second); - S32 selection_right = llmax(itHighlight->first, itHighlight->second) ; -// [/SL:KB] + S32 selection_left = llmin(itHighlight->first, itHighlight->second); + S32 selection_right = llmax(itHighlight->first, itHighlight->second); // is selection visible on this line? if (line_iter->mDocIndexEnd > selection_left && line_iter->mDocIndexStart < selection_right) @@ -449,14 +420,14 @@ void LLTextBase::drawHighlightsBackground(const highlight_list_t& highlights, co segment_set_t::iterator segment_iter; S32 segment_offset; getSegmentAndOffset(line_iter->mDocIndexStart, &segment_iter, &segment_offset); - + LLRect selection_rect; selection_rect.mLeft = line_iter->mRect.mLeft; selection_rect.mRight = line_iter->mRect.mLeft; selection_rect.mBottom = line_iter->mRect.mBottom; selection_rect.mTop = line_iter->mRect.mTop; - - for(;segment_iter != mSegments.end(); ++segment_iter, segment_offset = 0) + + for (; segment_iter != mSegments.end(); ++segment_iter, segment_offset = 0) { LLTextSegmentPtr segmentp = *segment_iter; @@ -469,7 +440,7 @@ void LLTextBase::drawHighlightsBackground(const highlight_list_t& highlights, co S32 segment_height = 0; // if selection after beginning of segment - if(selection_left >= segment_line_start) + if (selection_left >= segment_line_start) { S32 num_chars = llmin(selection_left, segment_line_end) - segment_line_start; segmentp->getDimensions(segment_offset, num_chars, segment_width, segment_height); @@ -495,31 +466,146 @@ void LLTextBase::drawHighlightsBackground(const highlight_list_t& highlights, co segmentp->getDimensions(segment_offset, num_chars, segment_width, segment_height); selection_rect.mRight += segment_width; -// [SL:KB] - Patch: Control-TextHighlight | Checked: 2013-12-30 (Catznip-3.6) continue; -// [/SL:KB] -// break; } } selection_rects.push_back(selection_rect); } -// [SL:KB] - Patch: Control-TextHighlight | Checked: 2013-12-30 (Catznip-3.6) // Only advance if the highlight ends on the current line if (itHighlight->second > line_iter->mDocIndexEnd) break; ++itHighlight; } -// [/SL:KB] } - + // Draw the selection box (we're using a box instead of reversing the colors on the selected text). gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); -// const LLColor4& color = mSelectedBGColor; F32 alpha = hasFocus() ? 0.7f : 0.3f; alpha *= getDrawContext().mAlpha; LLColor4 selection_color(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], alpha); + for (std::vector::iterator rect_it = selection_rects.begin(); + rect_it != selection_rects.end(); + ++rect_it) + { + LLRect selection_rect = *rect_it; + selection_rect = *rect_it; + selection_rect.translate(mVisibleTextRect.mLeft - content_display_rect.mLeft, mVisibleTextRect.mBottom - content_display_rect.mBottom); + gl_rect_2d(selection_rect, selection_color); + } + } +} +// [/SL:KB] + +std::vector LLTextBase::getSelctionRects() +{ + // Nor supposed to be called without selection + llassert(hasSelection()); + llassert(!mLineInfoList.empty()); + + std::vector selection_rects; + + S32 selection_left = llmin(mSelectionStart, mSelectionEnd); + S32 selection_right = llmax(mSelectionStart, mSelectionEnd); + + // Skip through the lines we aren't drawing. + LLRect content_display_rect = getVisibleDocumentRect(); + + // binary search for line that starts before top of visible buffer + line_list_t::const_iterator line_iter = std::lower_bound(mLineInfoList.begin(), mLineInfoList.end(), content_display_rect.mTop, compare_bottom()); + line_list_t::const_iterator end_iter = std::upper_bound(mLineInfoList.begin(), mLineInfoList.end(), content_display_rect.mBottom, compare_top()); + + bool done = false; + + // Find the coordinates of the selected area + for (; line_iter != end_iter && !done; ++line_iter) + { + // is selection visible on this line? + if (line_iter->mDocIndexEnd > selection_left && line_iter->mDocIndexStart < selection_right) + { + segment_set_t::iterator segment_iter; + S32 segment_offset; + getSegmentAndOffset(line_iter->mDocIndexStart, &segment_iter, &segment_offset); + + // Use F32 otherwise a string of multiple segments + // will accumulate a large error + F32 left_precise = line_iter->mRect.mLeft; + F32 right_precise = line_iter->mRect.mLeft; + + for (; segment_iter != mSegments.end(); ++segment_iter, segment_offset = 0) + { + LLTextSegmentPtr segmentp = *segment_iter; + + S32 segment_line_start = segmentp->getStart() + segment_offset; + S32 segment_line_end = llmin(segmentp->getEnd(), line_iter->mDocIndexEnd); + + if (segment_line_start > segment_line_end) break; + + F32 segment_width = 0; + S32 segment_height = 0; + + // if selection after beginning of segment + if (selection_left >= segment_line_start) + { + S32 num_chars = llmin(selection_left, segment_line_end) - segment_line_start; + segmentp->getDimensionsF32(segment_offset, num_chars, segment_width, segment_height); + left_precise += segment_width; + } + + // if selection_right == segment_line_end then that means we are the first character of the next segment + // or first character of the next line, in either case we want to add the length of the current segment + // to the selection rectangle and continue. + // if selection right > segment_line_end then selection spans end of current segment... + if (selection_right >= segment_line_end) + { + // extend selection slightly beyond end of line + // to indicate selection of newline character (use "n" character to determine width) + S32 num_chars = segment_line_end - segment_line_start; + segmentp->getDimensionsF32(segment_offset, num_chars, segment_width, segment_height); + right_precise += segment_width; + } + // else if selection ends on current segment... + else + { + S32 num_chars = selection_right - segment_line_start; + segmentp->getDimensionsF32(segment_offset, num_chars, segment_width, segment_height); + right_precise += segment_width; + + break; + } + } + + LLRect selection_rect; + selection_rect.mLeft = left_precise; + selection_rect.mRight = right_precise; + selection_rect.mBottom = line_iter->mRect.mBottom; + selection_rect.mTop = line_iter->mRect.mTop; + + selection_rects.push_back(selection_rect); + } + } + + return selection_rects; +} + +// Draws the black box behind the selected text +void LLTextBase::drawSelectionBackground() +{ + // Draw selection even if we don't have keyboard focus for search/replace + if (hasSelection() && !mLineInfoList.empty()) + { + std::vector selection_rects = getSelctionRects(); + + // Draw the selection box (we're using a box instead of reversing the colors on the selected text). + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + const LLColor4& color = mSelectedBGColor; + F32 alpha = hasFocus() ? 0.7f : 0.3f; + alpha *= getDrawContext().mAlpha; + + LLColor4 selection_color(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], alpha); + LLRect content_display_rect = getVisibleDocumentRect(); + for (std::vector::iterator rect_it = selection_rects.begin(); rect_it != selection_rects.end(); ++rect_it) @@ -2790,7 +2876,7 @@ S32 LLTextBase::getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round, } S32 pos = getLength(); - S32 start_x = line_iter->mRect.mLeft + doc_rect.mLeft; + F32 start_x = line_iter->mRect.mLeft + doc_rect.mLeft; segment_set_t::iterator line_seg_iter; S32 line_seg_offset; @@ -2802,8 +2888,9 @@ S32 LLTextBase::getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round, S32 segment_line_start = segmentp->getStart() + line_seg_offset; S32 segment_line_length = llmin(segmentp->getEnd(), line_iter->mDocIndexEnd) - segment_line_start; - S32 text_width, text_height; - bool newline = segmentp->getDimensions(line_seg_offset, segment_line_length, text_width, text_height); + F32 text_width; + S32 text_height; + bool newline = segmentp->getDimensionsF32(line_seg_offset, segment_line_length, text_width, text_height); if(newline) { @@ -2823,8 +2910,9 @@ S32 LLTextBase::getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round, S32 offset; if (!segmentp->canEdit()) { - S32 segment_width, segment_height; - segmentp->getDimensions(0, segmentp->getEnd() - segmentp->getStart(), segment_width, segment_height); + F32 segment_width; + S32 segment_height; + segmentp->getDimensionsF32(0, segmentp->getEnd() - segmentp->getStart(), segment_width, segment_height); if (round && local_x - start_x > segment_width / 2) { offset = segment_line_length; @@ -2871,17 +2959,11 @@ LLRect LLTextBase::getDocRectFromDocIndex(S32 pos) const return LLRect(); } - LLRect doc_rect; - // clamp pos to valid values pos = llclamp(pos, 0, mLineInfoList.back().mDocIndexEnd - 1); line_list_t::const_iterator line_iter = std::upper_bound(mLineInfoList.begin(), mLineInfoList.end(), pos, line_end_compare()); - doc_rect.mLeft = line_iter->mRect.mLeft; - doc_rect.mBottom = line_iter->mRect.mBottom; - doc_rect.mTop = line_iter->mRect.mTop; - segment_set_t::iterator line_seg_iter; S32 line_seg_offset; segment_set_t::iterator cursor_seg_iter; @@ -2889,6 +2971,8 @@ LLRect LLTextBase::getDocRectFromDocIndex(S32 pos) const getSegmentAndOffset(line_iter->mDocIndexStart, &line_seg_iter, &line_seg_offset); getSegmentAndOffset(pos, &cursor_seg_iter, &cursor_seg_offset); + F32 doc_left_precise = line_iter->mRect.mLeft; + while(line_seg_iter != mSegments.end()) { const LLTextSegmentPtr segmentp = *line_seg_iter; @@ -2896,18 +2980,20 @@ LLRect LLTextBase::getDocRectFromDocIndex(S32 pos) const if (line_seg_iter == cursor_seg_iter) { // cursor advanced to right based on difference in offset of cursor to start of line - S32 segment_width, segment_height; - segmentp->getDimensions(line_seg_offset, cursor_seg_offset - line_seg_offset, segment_width, segment_height); - doc_rect.mLeft += segment_width; + F32 segment_width; + S32 segment_height; + segmentp->getDimensionsF32(line_seg_offset, cursor_seg_offset - line_seg_offset, segment_width, segment_height); + doc_left_precise += segment_width; break; } else { // add remainder of current text segment to cursor position - S32 segment_width, segment_height; - segmentp->getDimensions(line_seg_offset, (segmentp->getEnd() - segmentp->getStart()) - line_seg_offset, segment_width, segment_height); - doc_rect.mLeft += segment_width; + F32 segment_width; + S32 segment_height; + segmentp->getDimensionsF32(line_seg_offset, (segmentp->getEnd() - segmentp->getStart()) - line_seg_offset, segment_width, segment_height); + doc_left_precise += segment_width; // offset will be 0 for all segments after the first line_seg_offset = 0; // go to next text segment on this line @@ -2915,6 +3001,11 @@ LLRect LLTextBase::getDocRectFromDocIndex(S32 pos) const } } + LLRect doc_rect; + doc_rect.mLeft = doc_left_precise; + doc_rect.mBottom = line_iter->mRect.mBottom; + doc_rect.mTop = line_iter->mRect.mTop; + // set rect to 0 width doc_rect.mRight = doc_rect.mLeft; diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h index de3d766acc..fa15b17b89 100644 --- a/indra/llui/lltextbase.h +++ b/indra/llui/lltextbase.h @@ -685,6 +685,8 @@ protected: return mLabel.getString() + getToolTip(); } + std::vector getSelctionRects(); + protected: // text segmentation and flow segment_set_t mSegments; diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index 199ee4e6db..f002219b3e 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -353,6 +353,7 @@ struct LLWindowWin32::LLWindowWin32Thread : public LL::ThreadPool { try { + LL_DEBUGS("Window") << "post( callable ) to work queue" << LL_ENDL; // extra debug for threaded window handler getQueue().post(std::forward(func)); } catch (const LLThreadSafeQueueInterrupt&) @@ -3136,18 +3137,54 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ { LLMutexLock lock(&window_imp->mRawMouseMutex); - S32 speed; - const S32 DEFAULT_SPEED(10); - SystemParametersInfo(SPI_GETMOUSESPEED, 0, &speed, 0); - if (speed == DEFAULT_SPEED) + bool absolute_coordinates = (raw->data.mouse.usFlags & MOUSE_MOVE_ABSOLUTE); + + if (absolute_coordinates) { - window_imp->mRawMouseDelta.mX += raw->data.mouse.lLastX; - window_imp->mRawMouseDelta.mY -= raw->data.mouse.lLastY; + static S32 prev_absolute_x = 0; + static S32 prev_absolute_y = 0; + S32 absolute_x; + S32 absolute_y; + + if ((raw->data.mouse.usFlags & 0x10) == 0x10) // touch screen? touch? Not defined in header + { + // touch screen spams (0,0) coordinates in a number of situations + // (0,0) might need to be filtered + absolute_x = raw->data.mouse.lLastX; + absolute_y = raw->data.mouse.lLastY; + } + else + { + bool v_desktop = (raw->data.mouse.usFlags & MOUSE_VIRTUAL_DESKTOP) == MOUSE_VIRTUAL_DESKTOP; + + S32 width = GetSystemMetrics(v_desktop ? SM_CXVIRTUALSCREEN : SM_CXSCREEN); + S32 height = GetSystemMetrics(v_desktop ? SM_CYVIRTUALSCREEN : SM_CYSCREEN); + + absolute_x = (raw->data.mouse.lLastX / 65535.0f) * width; + absolute_y = (raw->data.mouse.lLastY / 65535.0f) * height; + } + + window_imp->mRawMouseDelta.mX += absolute_x - prev_absolute_x; + window_imp->mRawMouseDelta.mY -= absolute_y - prev_absolute_y; + + prev_absolute_x = absolute_x; + prev_absolute_y = absolute_y; } else { - window_imp->mRawMouseDelta.mX += round((F32)raw->data.mouse.lLastX * (F32)speed / DEFAULT_SPEED); - window_imp->mRawMouseDelta.mY -= round((F32)raw->data.mouse.lLastY * (F32)speed / DEFAULT_SPEED); + S32 speed; + const S32 DEFAULT_SPEED(10); + SystemParametersInfo(SPI_GETMOUSESPEED, 0, &speed, 0); + if (speed == DEFAULT_SPEED) + { + window_imp->mRawMouseDelta.mX += raw->data.mouse.lLastX; + window_imp->mRawMouseDelta.mY -= raw->data.mouse.lLastY; + } + else + { + window_imp->mRawMouseDelta.mX += round((F32)raw->data.mouse.lLastX * (F32)speed / DEFAULT_SPEED); + window_imp->mRawMouseDelta.mY -= round((F32)raw->data.mouse.lLastY * (F32)speed / DEFAULT_SPEED); + } } } } @@ -4300,7 +4337,10 @@ void LLWindowWin32::handleCompositionMessage(const U32 indexes) if (needs_update) { - mPreeditor->resetPreedit(); + if (preedit_string.length() != 0 || result_string.length() != 0) + { + mPreeditor->resetPreedit(); + } if (result_string.length() > 0) { @@ -4737,7 +4777,10 @@ void LLWindowWin32::LLWindowWin32Thread::run() //process any pending functions getQueue().runPending(); } - + // This is very verbose even for debug so it has it's own debug tag + LL_DEBUGS("WindowVerbose") << "PreCheck Done - closed=" << getQueue().isClosed() << " size=" << getQueue().size() << LL_ENDL; + // + #if 0 { LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("w32t - Sleep"); @@ -4746,6 +4789,7 @@ void LLWindowWin32::LLWindowWin32Thread::run() } #endif } + logger.always("done - queue closed on windows thread.");// extra debug for threaded window handler } void LLWindowWin32::post(const std::function& func) diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index accbf71a85..e25033ca5c 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -132,6 +132,7 @@ set(viewer_SOURCE_FILES fsfloaterradar.cpp fsfloatersearch.cpp fsfloaterstatistics.cpp + fsfloaterstreamtitle.cpp fsfloaterteleporthistory.cpp fsfloatervoicecontrols.cpp fsfloatervolumecontrols.cpp @@ -356,9 +357,9 @@ set(viewer_SOURCE_FILES llfloaternotificationsconsole.cpp llfloaternotificationstabbed.cpp llfloateroutfitphotopreview.cpp - llfloateroutfitsnapshot.cpp llfloaterobjectweights.cpp llfloateropenobject.cpp + llfloatersimpleoutfitsnapshot.cpp llfloaterpathfindingcharacters.cpp llfloaterpathfindingconsole.cpp llfloaterpathfindinglinksets.cpp @@ -909,6 +910,7 @@ set(viewer_HEADER_FILES fsfloaterradar.h fsfloatersearch.h fsfloaterstatistics.h + fsfloaterstreamtitle.h fsfloaterteleporthistory.h fsfloatervoicecontrols.h fsfloatervolumecontrols.h @@ -1139,9 +1141,9 @@ set(viewer_HEADER_FILES llfloaternotificationsconsole.h llfloaternotificationstabbed.h llfloateroutfitphotopreview.h - llfloateroutfitsnapshot.h llfloaterobjectweights.h llfloateropenobject.h + llfloatersimpleoutfitsnapshot.h llfloaterpathfindingcharacters.h llfloaterpathfindingconsole.h llfloaterpathfindinglinksets.h diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index b7e35e8559..9df2d8c616 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -6951,11 +6951,11 @@ Type String Value - https://search.[GRID]/?query_term=[QUERY]&search_type=[TYPE][COLLECTION]&maturity=[MATURITY]&lang=[LANGUAGE]&sid=[SESSION_ID] + https://search.[GRID]/viewer/?query_term=[QUERY]&search_type=[TYPE][COLLECTION]&maturity=[MATURITY]&lang=[LANGUAGE]&sid=[SESSION_ID] Backup 0 GuidebookURL @@ -18336,6 +18336,17 @@ Change of this parameter will affect the layout of buttons in notification toast Value 0 + MediaSoundsEarLocation + + Comment + Location of the virtual ear for media and sounds + Persist + 1 + Type + S32 + Value + 0 + VoiceHost Comment diff --git a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl index f18f4da640..617aa80f52 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl @@ -230,7 +230,7 @@ void main() #if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_MASK) // Comparing floats cast from 8-bit values, produces acne right at the 8-bit transition points - float bias = 0.001953125; // 1/512, or half an 8-bit quantization + float bias = 0.001953125; // 1/512, or half an 8-bit quantization (SL-18637) if (diffcol.a < minimum_alpha-bias) { discard; diff --git a/indra/newview/fschathistory.cpp b/indra/newview/fschathistory.cpp index e3923c60e0..2ea814e2f3 100644 --- a/indra/newview/fschathistory.cpp +++ b/indra/newview/fschathistory.cpp @@ -691,10 +691,10 @@ public: void showInspector() { -// if (mAvatarID.isNull() && CHAT_SOURCE_SYSTEM != mSourceType) return; +// if (mAvatarID.isNull() && CHAT_SOURCE_SYSTEM != mSourceType && CHAT_SOURCE_REGION != mSourceType) return; // [RLVa:KB] - Checked: 2010-04-22 (RLVa-1.2.2a) | Added: RLVa-1.2.0f // Don't double-click show the inspector if we're not showing the info control - if ( (!mShowInfoCtrl) || (mAvatarID.isNull() && CHAT_SOURCE_SYSTEM != mSourceType) ) return; + if ( (!mShowInfoCtrl) || (mAvatarID.isNull() && CHAT_SOURCE_SYSTEM != mSourceType && CHAT_SOURCE_REGION != mSourceType) ) return; // [/RLVa:KB] if (mSourceType == CHAT_SOURCE_OBJECT) @@ -892,6 +892,7 @@ public: icon->setValue(LLSD("OBJECT_Icon")); break; case CHAT_SOURCE_SYSTEM: + case CHAT_SOURCE_REGION: //icon->setValue(LLSD("SL_Logo")); // FS:LO FIRE-1439 - Clickable avatar names on local chat radar crossing reports if(chat.mChatType == CHAT_TYPE_RADAR) @@ -1116,9 +1117,9 @@ protected: void showInfoCtrl() { -// const bool isVisible = !mAvatarID.isNull() && !mFrom.empty() && (CHAT_SOURCE_SYSTEM != mSourceType || mType == CHAT_TYPE_RADAR);; +// const bool isVisible = !mAvatarID.isNull() && !mFrom.empty() && (CHAT_SOURCE_SYSTEM != mSourceType || mType == CHAT_TYPE_RADAR) && CHAT_SOURCE_REGION != mSourceType; // [RLVa:KB] - Checked: 2010-04-22 (RLVa-1.2.2a) | Added: RLVa-1.2.0f - const bool isVisible = mShowInfoCtrl && !mAvatarID.isNull() && !mFrom.empty() && (CHAT_SOURCE_SYSTEM != mSourceType || mType == CHAT_TYPE_RADAR);; + const bool isVisible = mShowInfoCtrl && !mAvatarID.isNull() && !mFrom.empty() && (CHAT_SOURCE_SYSTEM != mSourceType || mType == CHAT_TYPE_RADAR) && CHAT_SOURCE_REGION != mSourceType; // [/RLVa:KB] if (isVisible) { @@ -1637,9 +1638,9 @@ void FSChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL appendText(chat.mFromName + delimiter, prependNewLineState, link_params); // FIRE-8600: TAB out of chat history prependNewLineState = false; } -// else if (chat.mFromName != SYSTEM_FROM && chat.mFromID.notNull() && !message_from_log) +// else if (chat.mFromName != SYSTEM_FROM && chat.mFromID.notNull() && !message_from_log && chat.mSourceType != CHAT_SOURCE_REGION) // [RLVa:KB] - Checked: 2010-04-22 (RLVa-1.2.0f) | Added: RLVa-1.2.0f - else if (chat.mFromName != SYSTEM_FROM && chat.mFromID.notNull() && !message_from_log && !chat.mRlvNamesFiltered) + else if (chat.mFromName != SYSTEM_FROM && chat.mFromID.notNull() && !message_from_log && chat.mSourceType != CHAT_SOURCE_REGION && !chat.mRlvNamesFiltered) // [/RLVa:KB] { name_params.color = name_color; diff --git a/indra/newview/fsfloaterim.cpp b/indra/newview/fsfloaterim.cpp index 591d76f91e..8591ef1879 100644 --- a/indra/newview/fsfloaterim.cpp +++ b/indra/newview/fsfloaterim.cpp @@ -1481,6 +1481,7 @@ void FSFloaterIM::updateMessages() std::string from = msg["from"].asString(); std::string message = msg["message"].asString(); bool is_history = msg["is_history"].asBoolean(); + bool is_region_msg = msg["is_region_msg"].asBoolean(); LLChat chat; chat.mFromID = from_id; @@ -1488,7 +1489,11 @@ void FSFloaterIM::updateMessages() chat.mFromName = from; chat.mTimeStr = time; chat.mChatStyle = is_history ? CHAT_STYLE_HISTORY : chat.mChatStyle; - + if (is_region_msg) + { + chat.mSourceType = CHAT_SOURCE_REGION; + } + // Bold group moderators' chat -KC // FS-1734 seperate name and text styles for moderator //if (!is_history && bold_mods_chat && pIMSession && pIMSession->mSpeakers) diff --git a/indra/newview/fsfloaternearbychat.cpp b/indra/newview/fsfloaternearbychat.cpp index 70557c4c8b..aa49fc0e64 100644 --- a/indra/newview/fsfloaternearbychat.cpp +++ b/indra/newview/fsfloaternearbychat.cpp @@ -67,7 +67,6 @@ #include "llstylemap.h" #include "lltextbox.h" #include "lltrans.h" -#include "lltranslate.h" #include "llviewercontrol.h" #include "llviewermenu.h"//for gMenuHolder #include "llviewerstats.h" @@ -142,8 +141,6 @@ BOOL FSFloaterNearbyChat::postBuild() mChatLayoutPanelHeight = mChatLayoutPanel->getRect().getHeight(); mInputEditorPad = mChatLayoutPanelHeight - mInputEditor->getRect().getHeight(); - enableTranslationButton(LLTranslate::isTranslationConfigured()); - getChild("chat_history_btn")->setCommitCallback(boost::bind(&FSFloaterNearbyChat::onHistoryButtonClicked, this)); getChild("chat_search_btn")->setCommitCallback(boost::bind(&FSFloaterNearbyChat::onSearchButtonClicked, this)); @@ -665,11 +662,6 @@ BOOL FSFloaterNearbyChat::getVisible() return is_active && !im_container->isMinimized() && im_container->getVisible(); } -void FSFloaterNearbyChat::enableTranslationButton(bool enabled) -{ - getChildView("translate_btn")->setEnabled(enabled); -} - // virtual BOOL FSFloaterNearbyChat::handleKeyHere( KEY key, MASK mask ) { diff --git a/indra/newview/fsfloaternearbychat.h b/indra/newview/fsfloaternearbychat.h index 58276d8be4..05fd42e210 100644 --- a/indra/newview/fsfloaternearbychat.h +++ b/indra/newview/fsfloaternearbychat.h @@ -87,7 +87,6 @@ public: void updateFSUseNearbyChatConsole(const LLSD &data); static bool isWordsName(const std::string& name); - void enableTranslationButton(bool enabled); LLChatEntry* getChatBox() { return mInputEditor; } S32 getMessageArchiveLength() {return mMessageArchive.size();} diff --git a/indra/newview/fsfloaterstreamtitle.cpp b/indra/newview/fsfloaterstreamtitle.cpp new file mode 100644 index 0000000000..b99f586387 --- /dev/null +++ b/indra/newview/fsfloaterstreamtitle.cpp @@ -0,0 +1,292 @@ +/** + * @file fsfloaterstreamtitle.cpp + * @brief Class for the stream title and history floater + * + * $LicenseInfo:firstyear=2022&license=viewerlgpl$ + * Phoenix Firestorm Viewer Source Code + * Copyright (c) 2022 Ansariel Hiller @ Second Life + * + * 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 + * + * The Phoenix Firestorm Project, Inc., 1831 Oakwood Drive, Fairmont, Minnesota 56031-3225 USA + * http://www.firestormviewer.org + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "fsfloaterstreamtitle.h" + +#include "fsscrolllistctrl.h" +#include "llaudioengine.h" +#include "llbutton.h" +#include "llfloaterreg.h" +#include "lltextbox.h" +#include "llviewercontrol.h" + +static constexpr size_t MAX_HISTORY_ENTRIES{ 10 }; +static constexpr F32 SCROLL_STEP_DELAY{ 0.25f }; +static constexpr F32 SCROLL_END_DELAY{ 4.f }; + +FSStreamTitleManager::~FSStreamTitleManager() +{ + if (mMetadataUpdateConnection.connected()) + { + mMetadataUpdateConnection.disconnect(); + } +} + +void FSStreamTitleManager::initSingleton() +{ + if (!gAudiop || !gAudiop->getStreamingAudioImpl()) + { + return; + } + + mMetadataUpdateConnection = gAudiop->getStreamingAudioImpl()->setMetadataUpdateCallback(std::bind(&FSStreamTitleManager::processMetadataUpdate, this, std::placeholders::_1)); + processMetadataUpdate(gAudiop->getStreamingAudioImpl()->getCurrentMetadata()); +} + +void FSStreamTitleManager::processMetadataUpdate(const LLSD& metadata) noexcept +{ + std::string chat{}; + + if (metadata.has("ARTIST")) + { + chat = metadata["ARTIST"].asString(); + } + if (metadata.has("TITLE")) + { + if (chat.length() > 0) + { + chat.append(" - "); + } + chat.append(metadata["TITLE"].asString()); + } + + if (chat != mCurrentStreamTitle) + { + mCurrentStreamTitle = std::move(chat); + + if (!mCurrentStreamTitle.empty() && (mStreamTitleHistory.empty() || mStreamTitleHistory.back() != mCurrentStreamTitle)) + { + mStreamTitleHistory.emplace_back(mCurrentStreamTitle); + + if (mStreamTitleHistory.size() > MAX_HISTORY_ENTRIES) + { + mStreamTitleHistory.erase(mStreamTitleHistory.begin()); + } + + mHistoryUpdateSignal(mStreamTitleHistory); + } + + mUpdateSignal(mCurrentStreamTitle); + } +} + + +////////////////////////////////////////////////////////////////////////// +/// FSFloaterStreamTitleHistory +////////////////////////////////////////////////////////////////////////// + +FSFloaterStreamTitleHistory::FSFloaterStreamTitleHistory(const LLSD& key) + : LLFloater(key) +{ +} + +FSFloaterStreamTitleHistory::~FSFloaterStreamTitleHistory() +{ + if (mUpdateConnection.connected()) + { + mUpdateConnection.disconnect(); + } +} + +BOOL FSFloaterStreamTitleHistory::postBuild() +{ + mHistoryCtrl = findChild("history"); + + FSStreamTitleManager& instance = FSStreamTitleManager::instance(); + mUpdateConnection = instance.setHistoryUpdateCallback([this](const FSStreamTitleManager::history_vec_t& history) { updateHistory(history); }); + updateHistory(instance.getStreamTitleHistory()); + + return TRUE; +} + +void FSFloaterStreamTitleHistory::updateHistory(const FSStreamTitleManager::history_vec_t& history) +{ + mHistoryCtrl->clearRows(); + + for (const auto& entry : history) + { + LLSD data; + data["columns"][0]["name"] = "title"; + data["columns"][0]["value"] = entry; + + mHistoryCtrl->addElement(data, ADD_TOP); + } +} + +void FSFloaterStreamTitleHistory::setOwnerOrigin(LLView* owner) noexcept +{ + mOwner = owner->getHandle(); +} + +void FSFloaterStreamTitleHistory::draw() +{ + LLFloater::draw(); + + if (mOwner.get()) + { + static LLCachedControl max_opacity(gSavedSettings, "PickerContextOpacity", 0.4f); + drawConeToOwner(mContextConeOpacity, max_opacity, mOwner.get()); + } +} + + +////////////////////////////////////////////////////////////////////////// +/// FSFloaterStreamTitle +////////////////////////////////////////////////////////////////////////// + +FSFloaterStreamTitle::FSFloaterStreamTitle(const LLSD& key) + : LLFloater(key), LLEventTimer(SCROLL_STEP_DELAY) +{ + mEventTimer.stop(); +} + +FSFloaterStreamTitle::~FSFloaterStreamTitle() +{ + if (mUpdateConnection.connected()) + { + mUpdateConnection.disconnect(); + } +} + +BOOL FSFloaterStreamTitle::postBuild() +{ + mTitletext = findChild("streamtitle"); + mHistoryBtn = findChild("btn_history"); + + FSStreamTitleManager& instance = FSStreamTitleManager::instance(); + mUpdateConnection = instance.setUpdateCallback([this](std::string_view streamtitle) { updateStreamTitle(streamtitle); }); + updateStreamTitle(instance.getCurrentStreamTitle()); + + mHistoryBtn->setCommitCallback(std::bind(&FSFloaterStreamTitle::openHistory, this)); + + setVisibleCallback(boost::bind(&FSFloaterStreamTitle::closeHistory, this)); + + return TRUE; +} + +void FSFloaterStreamTitle::openHistory() noexcept +{ + LLFloater* root_floater = gFloaterView->getParentFloater(this); + FSFloaterStreamTitleHistory* history_floater = LLFloaterReg::showTypedInstance("fs_streamtitlehistory"); + + if (root_floater) + { + root_floater->addDependentFloater(history_floater); + history_floater->setOwnerOrigin(root_floater); + } + + mHistory = history_floater->getHandle(); +} + +void FSFloaterStreamTitle::closeHistory() noexcept +{ + if (mHistory.get()) + { + mHistory.get()->closeFloater(); + } +} + +void FSFloaterStreamTitle::updateStreamTitle(std::string_view streamtitle) noexcept +{ + if (streamtitle.empty()) + { + mTitletext->setText(getString("NoStream")); + } + else + { + mTitletext->setText(static_cast(streamtitle)); + } + + mCurrentTitle = mTitletext->getText(); + mCurrentDrawnTitle = mCurrentTitle; + + mTitletext->setToolTip(mCurrentTitle); + + checkTitleWidth(); +} + +void FSFloaterStreamTitle::reshape(S32 width, S32 height, BOOL called_from_parent) +{ + LLFloater::reshape(width, height, called_from_parent); + checkTitleWidth(); +} + +void FSFloaterStreamTitle::checkTitleWidth() noexcept +{ + if (!mTitletext) + { + return; + } + + S32 text_width = mTitletext->getFont()->getWidth(mCurrentTitle); + S32 textbox_width = mTitletext->getRect().getWidth(); + + if (text_width > textbox_width) + { + mResetTitle = false; + mEventTimer.start(); + } + else + { + mEventTimer.stop(); + mTitletext->setText(mCurrentTitle); + mCurrentDrawnTitle = mCurrentTitle; + } +} + +BOOL FSFloaterStreamTitle::tick() +{ + if (mResetTitle) + { + mPeriod = SCROLL_END_DELAY; + mEventTimer.reset(); + mCurrentDrawnTitle = mCurrentTitle; + mResetTitle = false; + } + else + { + mPeriod = SCROLL_STEP_DELAY; + mEventTimer.reset(); + mCurrentDrawnTitle.erase(mCurrentDrawnTitle.begin()); + } + + mTitletext->setText(mCurrentDrawnTitle); + + S32 text_width = mTitletext->getFont()->getWidth(mCurrentDrawnTitle); + S32 textbox_width = mTitletext->getRect().getWidth(); + + if (textbox_width > text_width) + { + mPeriod = SCROLL_END_DELAY; + mEventTimer.reset(); + mResetTitle = true; + } + + return FALSE; +} diff --git a/indra/newview/fsfloaterstreamtitle.h b/indra/newview/fsfloaterstreamtitle.h new file mode 100644 index 0000000000..ac656e23f7 --- /dev/null +++ b/indra/newview/fsfloaterstreamtitle.h @@ -0,0 +1,128 @@ +/** + * @file fsfloaterstreamtitle.h + * @brief Class for the stream title and history floater + * + * $LicenseInfo:firstyear=2022&license=viewerlgpl$ + * Phoenix Firestorm Viewer Source Code + * Copyright (c) 2022 Ansariel Hiller @ Second Life + * + * 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 + * + * The Phoenix Firestorm Project, Inc., 1831 Oakwood Drive, Fairmont, Minnesota 56031-3225 USA + * http://www.firestormviewer.org + * $/LicenseInfo$ + */ + +#ifndef FS_FLOATERSTREAMTITLE_H +#define FS_FLOATERSTREAMTITLE_H + +#include "lleventtimer.h" +#include "llfloater.h" +#include "llsingleton.h" +#include "llstreamingaudio.h" +#include "streamtitledisplay.h" + +class LLButton; +class LLTextBox; +class FSScrollListCtrl; + +class FSStreamTitleManager : public LLSingleton +{ + LLSINGLETON_EMPTY_CTOR(FSStreamTitleManager); + +public: + ~FSStreamTitleManager(); + + using history_vec_t = std::vector; + + using streamtitle_update_callback_t = boost::signals2::signal; + boost::signals2::connection setUpdateCallback(const streamtitle_update_callback_t::slot_type& cb) noexcept + { + return mUpdateSignal.connect(cb); + } + + using streamtitle_history_update_callback_t = boost::signals2::signal; + boost::signals2::connection setHistoryUpdateCallback(const streamtitle_history_update_callback_t::slot_type& cb) noexcept + { + return mHistoryUpdateSignal.connect(cb); + } + + std::string getCurrentStreamTitle() const noexcept { return mCurrentStreamTitle; } + const history_vec_t& getStreamTitleHistory() const noexcept { return mStreamTitleHistory; } + +protected: + void initSingleton() override; + void processMetadataUpdate(const LLSD& metadata) noexcept; + + boost::signals2::connection mMetadataUpdateConnection; + streamtitle_update_callback_t mUpdateSignal; + streamtitle_history_update_callback_t mHistoryUpdateSignal; + + std::string mCurrentStreamTitle{}; + history_vec_t mStreamTitleHistory{}; +}; + +class FSFloaterStreamTitleHistory : public LLFloater +{ +public: + FSFloaterStreamTitleHistory(const LLSD& key); + virtual ~FSFloaterStreamTitleHistory(); + + BOOL postBuild() override; + void draw() override; + void setOwnerOrigin(LLView* owner) noexcept; + +protected: + void updateHistory(const FSStreamTitleManager::history_vec_t& history); + + FSScrollListCtrl* mHistoryCtrl{ nullptr }; + + boost::signals2::connection mUpdateConnection{}; + + LLHandle mOwner{}; + F32 mContextConeOpacity{ 0.f }; +}; + +class FSFloaterStreamTitle : public LLFloater, LLEventTimer +{ +public: + FSFloaterStreamTitle(const LLSD& key); + virtual ~FSFloaterStreamTitle(); + + BOOL postBuild() override; + void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE) override; + +private: + BOOL tick() override; + + void updateStreamTitle(std::string_view streamtitle) noexcept; + void openHistory() noexcept; + void closeHistory() noexcept; + void checkTitleWidth() noexcept; + + LLButton* mHistoryBtn{ nullptr }; + LLTextBox* mTitletext{ nullptr }; + + LLHandle mHistory{}; + + boost::signals2::connection mUpdateConnection{}; + + std::string mCurrentTitle{}; + std::string mCurrentDrawnTitle{}; + bool mResetTitle{ false }; + +}; + +#endif // FS_FLOATERSTREAMTITLE_H diff --git a/indra/newview/fsfloaterwearablefavorites.cpp b/indra/newview/fsfloaterwearablefavorites.cpp index bcf3a2cf6e..bbb1f50751 100644 --- a/indra/newview/fsfloaterwearablefavorites.cpp +++ b/indra/newview/fsfloaterwearablefavorites.cpp @@ -42,6 +42,8 @@ #include "rlvactions.h" #include "rlvlocks.h" +// Hello Kokua! Have fun yoinking! ;) + #define FS_WEARABLE_FAVORITES_FOLDER "#Wearable Favorites" static LLDefaultChildRegistry::Register r("fs_wearable_favorites_items_list"); @@ -85,7 +87,7 @@ LLUUID FSFloaterWearableFavorites::sFolderID = LLUUID(); FSFloaterWearableFavorites::FSFloaterWearableFavorites(const LLSD& key) : LLFloater(key), - mItemsList(NULL), + mItemsList(nullptr), mInitialized(false), mDADCallbackConnection() { @@ -199,6 +201,30 @@ BOOL FSFloaterWearableFavorites::handleKeyHere(KEY key, MASK mask) return LLFloater::handleKeyHere(key, mask); } +// static +std::optional FSFloaterWearableFavorites::getWearableFavoritesFolderID() +{ + LLUUID fs_root_cat_id = gInventory.findCategoryByName(ROOT_FIRESTORM_FOLDER); + if (!fs_root_cat_id.isNull()) + { + LLInventoryModel::item_array_t* items; + LLInventoryModel::cat_array_t* cats; + gInventory.getDirectDescendentsOf(fs_root_cat_id, cats, items); + if (cats) + { + for (const auto& cat : *cats) + { + if (cat->getName() == FS_WEARABLE_FAVORITES_FOLDER) + { + return cat->getUUID(); + } + } + } + } + + return std::nullopt; +} + // static void FSFloaterWearableFavorites::initCategory() { @@ -208,63 +234,30 @@ void FSFloaterWearableFavorites::initCategory() return; } - LLUUID fs_favs_id; - - LLUUID fs_root_cat_id = gInventory.findCategoryByName(ROOT_FIRESTORM_FOLDER); - if (!fs_root_cat_id.isNull()) + if (auto fs_favs_id = getWearableFavoritesFolderID(); fs_favs_id.has_value()) { - LLInventoryModel::item_array_t* items; - LLInventoryModel::cat_array_t* cats; - gInventory.getDirectDescendentsOf(fs_root_cat_id, cats, items); - if (cats) - { - for (LLInventoryModel::cat_array_t::iterator it = cats->begin(); it != cats->end(); ++it) - { - if ((*it)->getName() == FS_WEARABLE_FAVORITES_FOLDER) - { - fs_favs_id = (*it)->getUUID(); - break; - } - } - } + sFolderID = fs_favs_id.value(); } else { - fs_root_cat_id = gInventory.createNewCategory(gInventory.getRootFolderID(), LLFolderType::FT_NONE, ROOT_FIRESTORM_FOLDER); - } + LLUUID fs_root_cat_id = gInventory.findCategoryByName(ROOT_FIRESTORM_FOLDER); + if (fs_root_cat_id.isNull()) + { + fs_root_cat_id = gInventory.createNewCategory(gInventory.getRootFolderID(), LLFolderType::FT_NONE, ROOT_FIRESTORM_FOLDER); + } - if (fs_favs_id.isNull()) - { - fs_favs_id = gInventory.createNewCategory(fs_root_cat_id, LLFolderType::FT_NONE, FS_WEARABLE_FAVORITES_FOLDER); + sFolderID = gInventory.createNewCategory(fs_root_cat_id, LLFolderType::FT_NONE, FS_WEARABLE_FAVORITES_FOLDER); } - - sFolderID = fs_favs_id; } //static LLUUID FSFloaterWearableFavorites::getFavoritesFolder() { - if (sFolderID.notNull()) + if (!sFolderID.isNull()) { - return sFolderID; - } - - LLUUID fs_root_cat_id = gInventory.findCategoryByName(ROOT_FIRESTORM_FOLDER); - if (!fs_root_cat_id.isNull()) - { - LLInventoryModel::item_array_t* items; - LLInventoryModel::cat_array_t* cats; - gInventory.getDirectDescendentsOf(fs_root_cat_id, cats, items); - if (cats) + if (auto fs_favs_id = getWearableFavoritesFolderID(); fs_favs_id.has_value()) { - for (LLInventoryModel::cat_array_t::iterator it = cats->begin(); it != cats->end(); ++it) - { - if ((*it)->getName() == FS_WEARABLE_FAVORITES_FOLDER) - { - sFolderID = (*it)->getUUID(); - break; - } - } + sFolderID = fs_favs_id.value(); } } @@ -283,7 +276,7 @@ void FSFloaterWearableFavorites::updateList(const LLUUID& folder_id) void FSFloaterWearableFavorites::onItemDAD(const LLUUID& item_id) { - link_inventory_object(sFolderID, item_id, LLPointer(NULL)); + link_inventory_object(sFolderID, item_id, LLPointer(nullptr)); } void FSFloaterWearableFavorites::handleRemove() @@ -291,9 +284,9 @@ void FSFloaterWearableFavorites::handleRemove() uuid_vec_t selected_item_ids; mItemsList->getSelectedUUIDs(selected_item_ids); - for (uuid_vec_t::iterator it = selected_item_ids.begin(); it != selected_item_ids.end(); ++it) + for (const auto& id : selected_item_ids) { - remove_inventory_item(*it, LLPointer(NULL)); + remove_inventory_item(id, LLPointer(nullptr)); } } @@ -378,4 +371,3 @@ void FSFloaterWearableFavorites::onDoubleClick() } } } - diff --git a/indra/newview/fsfloaterwearablefavorites.h b/indra/newview/fsfloaterwearablefavorites.h index 988428d86d..8f09524aa4 100644 --- a/indra/newview/fsfloaterwearablefavorites.h +++ b/indra/newview/fsfloaterwearablefavorites.h @@ -30,6 +30,7 @@ #include "llfloater.h" #include "llwearableitemslist.h" +#include class LLButton; class LLFilterEditor; @@ -92,6 +93,8 @@ private: void onOptionsMenuItemClicked(const LLSD& userdata); bool onOptionsMenuItemChecked(const LLSD& userdata); + static std::optional getWearableFavoritesFolderID(); + bool mInitialized; boost::signals2::connection mDADCallbackConnection; diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 5984f42118..5b306eb584 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -3485,12 +3485,11 @@ void LLAgent::processMaturityPreferenceFromServer(const LLSD &result, U8 perferr bool LLAgent::requestPostCapability(const std::string &capName, LLSD &postData, httpCallback_t cbSuccess, httpCallback_t cbFailure) { - std::string url; - - // FIRE-21323: Crashfix - //url = getRegion()->getCapability(capName); - url = getRegion() ? getRegion()->getCapability(capName) : ""; - // + if (!getRegion()) + { + return false; + } + std::string url = getRegion()->getCapability(capName); if (url.empty()) { diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 820f1e3395..c222a5bd14 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -225,7 +225,7 @@ #include "llcommandlineparser.h" #include "llfloatermemleak.h" #include "llfloaterreg.h" -#include "llfloateroutfitsnapshot.h" +#include "llfloatersimpleoutfitsnapshot.h" #include "llfloatersnapshot.h" #include "llsidepanelinventory.h" #include "llatmosphere.h" @@ -1483,7 +1483,6 @@ bool LLAppViewer::init() //LLSimpleton creations LLEnvironment::createInstance(); - LLEnvironment::getInstance()->initSingleton(); LLWorld::createInstance(); LLSelectMgr::createInstance(); LLViewerCamera::createInstance(); @@ -1769,7 +1768,9 @@ bool LLAppViewer::doFrame() { LLVoiceClient::getInstance()->terminate(); } - + // [FIRE-32453] [BUG-232971] disconnect sooner to force the cache write. + persistCachesAndSettings(); + // disconnectViewer(); resumeMainloopTimeout(); } @@ -1789,7 +1790,7 @@ bool LLAppViewer::doFrame() LL_PROFILE_ZONE_NAMED_CATEGORY_APP("df Snapshot") pingMainloopTimeout("Main:Snapshot"); LLFloaterSnapshot::update(); // take snapshots - LLFloaterOutfitSnapshot::update(); + LLFloaterSimpleOutfitSnapshot::update(); gGLActive = FALSE; } } @@ -2057,7 +2058,6 @@ bool LLAppViewer::cleanup() LLViewerCamera::deleteSingleton(); LL_INFOS() << "Viewer disconnected" << LL_ENDL; - if (gKeyboard) { gKeyboard->resetKeys(); @@ -4859,6 +4859,9 @@ void LLAppViewer::removeDumpDir() void LLAppViewer::forceQuit() { + // [FIRE-32453] [BUG-232971] disconnect sooner to force the cache write. + persistCachesAndSettings(); + // LLApp::setQuitting(); } @@ -6329,7 +6332,12 @@ void LLAppViewer::idleNetwork() } } add(LLStatViewer::NUM_NEW_OBJECTS, gObjectList.mNumNewObjects); - + // [FIRE-32453] [BUG-232971] disconnect sooner to force the cache write. + if(gDisconnected) + { + return; + } + // // Retransmit unacknowledged packets. gXferManager->retransmitUnackedPackets(); gAssetStorage->checkForTimeouts(); @@ -6351,7 +6359,42 @@ void LLAppViewer::idleNetwork() mAgentRegionLastAlive = this_region_alive; } } +void LLAppViewer::persistCachesAndSettings() +{ + // Save inventory to disk if appropriate + if (gInventory.isInventoryUsable() + && gAgent.getID().notNull()) // Shouldn't be null at this stage + { + LL_INFOS() << "Saving Inventory Cache" << LL_ENDL; + gInventory.cache(gInventory.getRootFolderID(), gAgent.getID()); + if (gInventory.getLibraryRootFolderID().notNull() + && gInventory.getLibraryOwnerID().notNull()) + { + gInventory.cache( + gInventory.getLibraryRootFolderID(), + gInventory.getLibraryOwnerID()); + } + LL_INFOS() << "Saving Inventory Cache : COMPLETED" << LL_ENDL; + } + else + { + LL_INFOS() << "Not Saving Inventory Cache : Inventory is currently unusable" << LL_ENDL; + } + // Persist name cache + LLAvatarNameCache::instance().setCustomNameCheckCallback(LLAvatarNameCache::custom_name_check_callback_t()); // Contact sets + LL_INFOS() << "Saving Name Cache" << LL_ENDL; + saveNameCache(); + LL_INFOS() << "Saving Name Cache : COMPLETED" << LL_ENDL; + // Save experience cache if appropriate + if (LLExperienceCache::instanceExists()) + { + LL_INFOS() << "Saving Experience Cache" << LL_ENDL; + LLExperienceCache::instance().cleanup(); + LL_INFOS() << "Saving Experience Cache : COMPLETED" << LL_ENDL; + } + +} void LLAppViewer::disconnectViewer() { if (gDisconnected) @@ -6387,30 +6430,32 @@ void LLAppViewer::disconnectViewer() { LLSelectMgr::getInstance()->deselectAll(); } + // [FIRE-32453] [BUG-232971] Persist before disconnect + // Moved to separate function + // // save inventory if appropriate + // if (gInventory.isInventoryUsable() + // && gAgent.getID().notNull()) // Shouldn't be null at this stage + // { + // gInventory.cache(gInventory.getRootFolderID(), gAgent.getID()); + // if (gInventory.getLibraryRootFolderID().notNull() + // && gInventory.getLibraryOwnerID().notNull()) + // { + // gInventory.cache( + // gInventory.getLibraryRootFolderID(), + // gInventory.getLibraryOwnerID()); + // } + // } - // save inventory if appropriate - if (gInventory.isInventoryUsable() - && gAgent.getID().notNull()) // Shouldn't be null at this stage - { - gInventory.cache(gInventory.getRootFolderID(), gAgent.getID()); - if (gInventory.getLibraryRootFolderID().notNull() - && gInventory.getLibraryOwnerID().notNull()) - { - gInventory.cache( - gInventory.getLibraryRootFolderID(), - gInventory.getLibraryOwnerID()); - } - } - - LLAvatarNameCache::instance().setCustomNameCheckCallback(LLAvatarNameCache::custom_name_check_callback_t()); // Contact sets - saveNameCache(); - if (LLExperienceCache::instanceExists()) - { - // TODO: LLExperienceCache::cleanup() logic should be moved to - // cleanupSingleton(). - LLExperienceCache::instance().cleanup(); - } + // LLAvatarNameCache::instance().setCustomNameCheckCallback(LLAvatarNameCache::custom_name_check_callback_t()); // Contact sets + // saveNameCache(); + // if (LLExperienceCache::instanceExists()) + // { + // // TODO: LLExperienceCache::cleanup() logic should be moved to + // // cleanupSingleton(). + // LLExperienceCache::instance().cleanup(); + // } + // // close inventory interface, close all windows LLSidepanelInventory::cleanup(); @@ -6440,7 +6485,7 @@ void LLAppViewer::disconnectViewer() LLDestroyClassList::instance().fireCallbacks(); cleanup_xfer_manager(); - gDisconnected = TRUE; + gDisconnected = TRUE; // Pass the connection state to LLUrlEntryParcel not to attempt // parcel info requests while disconnected. diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index 323cd21c5a..c548e3c5b8 100644 --- a/indra/newview/llappviewer.h +++ b/indra/newview/llappviewer.h @@ -287,6 +287,7 @@ private: void idleNetwork(); void sendLogoutRequest(); + void persistCachesAndSettings(); void disconnectViewer(); // *FIX: the app viewer class should be some sort of singleton, no? diff --git a/indra/newview/llaudiosourcevo.cpp b/indra/newview/llaudiosourcevo.cpp index 88c2777675..06a2249104 100644 --- a/indra/newview/llaudiosourcevo.cpp +++ b/indra/newview/llaudiosourcevo.cpp @@ -105,7 +105,7 @@ LLVector3d LLAudioSourceVO::getPosGlobal() const bool LLAudioSourceVO::isInCutOffRadius(const LLVector3d pos_global, const F32 cutoff) const { - static LLCachedControl ear_mode(gSavedSettings, "VoiceEarLocation", 0); + static LLCachedControl ear_mode(gSavedSettings, "MediaSoundsEarLocation", 0); LLVector3d pos_ear; @@ -116,9 +116,6 @@ bool LLAudioSourceVO::isInCutOffRadius(const LLVector3d pos_global, const F32 cu break; case 1: // avatar - case 2: - // voice support 'mixed' in '2' case with agent's position and camera's rotations - // but it is not defined in settings and uses camera as default pos_ear = gAgent.getPositionGlobal(); break; diff --git a/indra/newview/llavatarpropertiesprocessor.cpp b/indra/newview/llavatarpropertiesprocessor.cpp index 699f7d54b5..8750eb9f91 100644 --- a/indra/newview/llavatarpropertiesprocessor.cpp +++ b/indra/newview/llavatarpropertiesprocessor.cpp @@ -147,16 +147,14 @@ void LLAvatarPropertiesProcessor::sendRequest(const LLUUID& avatar_id, EAvatarPr void LLAvatarPropertiesProcessor::sendGenericRequest(const LLUUID& avatar_id, EAvatarProcessorType type, const std::string &method) { -// First run at profile behaviour fix for OpenSim -#ifdef OPENSIM // maintain legacy behaviour for now + // First run at profile behaviour fix for OpenSim // Suppress duplicate requests while waiting for a response from the network if (isPendingRequest(avatar_id, type)) { // waiting for a response, don't re-request return; } -#endif //OPENSIM -// + // // indicate we're going to make a request addPendingRequest(avatar_id, type); @@ -190,34 +188,8 @@ void LLAvatarPropertiesProcessor::initAgentProfileCapRequest(const LLUUID& avata } void LLAvatarPropertiesProcessor::sendAvatarPropertiesRequest(const LLUUID& avatar_id) { -// maintian legacy behaviour for OpenSim - if(!gAgent.getRegionCapability("AgentProfile").empty()) - { -// - sendRequest(avatar_id, APT_PROPERTIES, "AvatarPropertiesRequest"); - } -// maintian legacy behaviour for OpenSim -#ifdef OPENSIM - else - { - // this is the startup state when send_complete_agent_movement() message is sent. - // Before this, the AvatarPropertiesRequest message - // won't work so don't bother trying - if (LLStartUp::getStartupState() <= STATE_AGENT_SEND) - { - return; - } - - if (isPendingRequest(avatar_id, APT_PROPERTIES)) - { - // waiting for a response, don't re-request - return; - } - sendAvatarPropertiesRequestMessage(avatar_id); - } -#endif + sendRequest(avatar_id, APT_PROPERTIES, "AvatarPropertiesRequest"); } -// void LLAvatarPropertiesProcessor::sendAvatarPicksRequest(const LLUUID& avatar_id) { diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp index c06e2793db..293c92cc49 100644 --- a/indra/newview/llchathistory.cpp +++ b/indra/newview/llchathistory.cpp @@ -670,10 +670,10 @@ public: void showInspector() { -// if (mAvatarID.isNull() && CHAT_SOURCE_SYSTEM != mSourceType) return; +// if (mAvatarID.isNull() && CHAT_SOURCE_SYSTEM != mSourceType && CHAT_SOURCE_REGION != mSourceType) return; // [RLVa:KB] - Checked: 2010-04-22 (RLVa-1.2.2a) | Added: RLVa-1.2.0f // Don't double-click show the inspector if we're not showing the info control - if ( (!mShowInfoCtrl) || (mAvatarID.isNull() && CHAT_SOURCE_SYSTEM != mSourceType) ) return; + if ( (!mShowInfoCtrl) || (mAvatarID.isNull() && CHAT_SOURCE_SYSTEM != mSourceType && CHAT_SOURCE_REGION != mSourceType) ) return; // [/RLVa:KB] if (mSourceType == CHAT_SOURCE_OBJECT) @@ -847,6 +847,7 @@ public: icon->setValue(LLSD("OBJECT_Icon")); break; case CHAT_SOURCE_SYSTEM: + case CHAT_SOURCE_REGION: icon->setValue(LLSD("SL_Logo")); break; case CHAT_SOURCE_TELEPORT: @@ -1000,9 +1001,9 @@ protected: void showInfoCtrl() { -// const bool isVisible = !mAvatarID.isNull() && !mFrom.empty() && CHAT_SOURCE_SYSTEM != mSourceType; +// const bool isVisible = !mAvatarID.isNull() && !mFrom.empty() && CHAT_SOURCE_SYSTEM != mSourceType && CHAT_SOURCE_REGION != mSourceType; // [RLVa:KB] - Checked: 2010-04-22 (RLVa-1.2.2a) | Added: RLVa-1.2.0f - const bool isVisible = mShowInfoCtrl && !mAvatarID.isNull() && !mFrom.empty() && CHAT_SOURCE_SYSTEM != mSourceType; + const bool isVisible = mShowInfoCtrl && !mAvatarID.isNull() && !mFrom.empty() && CHAT_SOURCE_SYSTEM != mSourceType && CHAT_SOURCE_REGION != mSourceType; // [/RLVa:KB] if (isVisible) { @@ -1413,9 +1414,9 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL mEditor->appendText(chat.mFromName + delimiter, prependNewLineState, link_params); prependNewLineState = false; } -// else if (chat.mFromName != SYSTEM_FROM && chat.mFromID.notNull() && !message_from_log) +// else if (chat.mFromName != SYSTEM_FROM && chat.mFromID.notNull() && !message_from_log && chat.mSourceType != CHAT_SOURCE_REGION) // [RLVa:KB] - Checked: 2010-04-22 (RLVa-1.2.0f) | Added: RLVa-1.2.0f - else if (chat.mFromName != SYSTEM_FROM && chat.mFromID.notNull() && !message_from_log && !chat.mRlvNamesFiltered) + else if (chat.mFromName != SYSTEM_FROM && chat.mFromID.notNull() && !message_from_log && chat.mSourceType != CHAT_SOURCE_REGION && !chat.mRlvNamesFiltered) // [/RLVa:KB] { LLStyle::Params link_params(body_message_params); diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h index 800d13df3e..3e4c37d6c2 100644 --- a/indra/newview/llconversationmodel.h +++ b/indra/newview/llconversationmodel.h @@ -90,7 +90,7 @@ public: virtual BOOL removeItem() { return FALSE; } virtual void removeBatch(std::vector& batch) { } virtual void move( LLFolderViewModelItem* parent_listener ) { } - virtual BOOL isItemCopyable() const { return FALSE; } + virtual bool isItemCopyable(bool can_copy_as_link = true) const { return false; } virtual BOOL copyToClipboard() const { return FALSE; } virtual BOOL cutToClipboard() { return FALSE; } virtual BOOL isClipboardPasteable() const { return FALSE; } diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp index 8db16ef5d0..65fef99da7 100644 --- a/indra/newview/lldrawpoolbump.cpp +++ b/indra/newview/lldrawpoolbump.cpp @@ -41,6 +41,7 @@ #include "lldrawable.h" #include "llface.h" #include "llsky.h" +#include "llstartup.h" #include "lltextureentry.h" #include "llviewercamera.h" #include "llviewertexturelist.h" @@ -80,11 +81,6 @@ static S32 bump_channel = -1; #define LL_BUMPLIST_MULTITHREADED 0 // TODO -- figure out why this doesn't work -// static -void LLStandardBumpmap::init() -{ - LLStandardBumpmap::restoreGL(); -} // static void LLStandardBumpmap::shutdown() @@ -95,7 +91,7 @@ void LLStandardBumpmap::shutdown() // static void LLStandardBumpmap::restoreGL() { - addstandard(); + addstandard(); } // static @@ -108,6 +104,12 @@ void LLStandardBumpmap::addstandard() return ; } + if (LLStartUp::getStartupState() < STATE_SEED_CAP_GRANTED) + { + // Not ready, need caps for images + return; + } + // can't assert; we destroyGL and restoreGL a lot during *first* startup, which populates this list already, THEN we explicitly init the list as part of *normal* startup. Sigh. So clear the list every time before we (re-)add the standard bumpmaps. //llassert( LLStandardBumpmap::sStandardBumpmapCount == 0 ); clear(); @@ -799,8 +801,6 @@ void LLBumpImageList::init() llassert( mBrightnessEntries.size() == 0 ); llassert( mDarknessEntries.size() == 0 ); - LLStandardBumpmap::init(); - LLStandardBumpmap::restoreGL(); sMainQueue = LL::WorkQueue::getInstance("mainloop"); sTexUpdateQueue = LL::WorkQueue::getInstance("LLImageGL"); // Share work queue with tex loader. diff --git a/indra/newview/lldrawpoolbump.h b/indra/newview/lldrawpoolbump.h index e8a027967b..cf463f4458 100644 --- a/indra/newview/lldrawpoolbump.h +++ b/indra/newview/lldrawpoolbump.h @@ -118,7 +118,6 @@ public: static void clear(); static void addstandard(); - static void init(); static void shutdown(); static void restoreGL(); static void destroyGL(); diff --git a/indra/newview/llenvironment.cpp b/indra/newview/llenvironment.cpp index c571064189..2e287bf8b5 100644 --- a/indra/newview/llenvironment.cpp +++ b/indra/newview/llenvironment.cpp @@ -955,26 +955,37 @@ void LLEnvironment::initSingleton() requestRegion(); - gAgent.addParcelChangedCallback([this]() { onParcelChange(); }); + if (!mParcelCallbackConnection.connected()) + { + mParcelCallbackConnection = gAgent.addParcelChangedCallback([this]() { onParcelChange(); }); - //TODO: This frequently results in one more request than we need. It isn't breaking, but should be nicer. - // We need to know new env version to fix this, without it we can only do full re-request - // Happens: on updates, on opening LLFloaterRegionInfo, on region crossing if info floater is open - LLRegionInfoModel::instance().setUpdateCallback([this]() { requestRegion(); }); - gAgent.addRegionChangedCallback([this]() { onRegionChange(); }); + //TODO: This frequently results in one more request than we need. It isn't breaking, but should be nicer. + // We need to know new env version to fix this, without it we can only do full re-request + // Happens: on updates, on opening LLFloaterRegionInfo, on region crossing if info floater is open + mRegionUpdateCallbackConnection = LLRegionInfoModel::instance().setUpdateCallback([this]() { requestRegion(); }); + mRegionChangeCallbackConnection = gAgent.addRegionChangedCallback([this]() { onRegionChange(); }); - gAgent.whenPositionChanged([this](const LLVector3 &localpos, const LLVector3d &) { onAgentPositionHasChanged(localpos); }); + mPositionCallbackConnection = gAgent.whenPositionChanged([this](const LLVector3 &localpos, const LLVector3d &) { onAgentPositionHasChanged(localpos); }); + } if (!gGenericDispatcher.isHandlerPresent(MESSAGE_PUSHENVIRONMENT)) { gGenericDispatcher.addHandler(MESSAGE_PUSHENVIRONMENT, &environment_push_dispatch_handler); } + LLEventPumps::instance().obtain(PUMP_EXPERIENCE).stopListening(LISTENER_NAME); LLEventPumps::instance().obtain(PUMP_EXPERIENCE).listen(LISTENER_NAME, [this](LLSD message) { listenExperiencePump(message); return false; }); } void LLEnvironment::cleanupSingleton() { + if (mParcelCallbackConnection.connected()) + { + mParcelCallbackConnection.disconnect(); + mRegionUpdateCallbackConnection.disconnect(); + mRegionChangeCallbackConnection.disconnect(); + mPositionCallbackConnection.disconnect(); + } LLEventPumps::instance().obtain(PUMP_EXPERIENCE).stopListening(LISTENER_NAME); } diff --git a/indra/newview/llenvironment.h b/indra/newview/llenvironment.h index 50845d1e35..0ae2bcdd90 100644 --- a/indra/newview/llenvironment.h +++ b/indra/newview/llenvironment.h @@ -426,6 +426,11 @@ private: bool mShowMoonBeacon; S32 mEditorCounter; + connection_t mParcelCallbackConnection; + connection_t mRegionUpdateCallbackConnection; + connection_t mRegionChangeCallbackConnection; + connection_t mPositionCallbackConnection; + struct UpdateInfo { typedef std::shared_ptr ptr_t; diff --git a/indra/newview/llfloater360capture.cpp b/indra/newview/llfloater360capture.cpp index c36cd14467..1620a201d7 100644 --- a/indra/newview/llfloater360capture.cpp +++ b/indra/newview/llfloater360capture.cpp @@ -84,7 +84,7 @@ LLFloater360Capture::~LLFloater360Capture() // Tell the Simulator not to send us everything anymore // and revert to the regular "keyhole" frustum of interest // list updates. - if (gSavedSettings.getBOOL("360CaptureUseInterestListCap")) + if (!LLApp::isExiting() && gSavedSettings.getBOOL("360CaptureUseInterestListCap")) { const bool send_everything = false; changeInterestListMode(send_everything); diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp index 9c9df55dc4..237eaebf07 100644 --- a/indra/newview/llfloaterimnearbychat.cpp +++ b/indra/newview/llfloaterimnearbychat.cpp @@ -317,7 +317,6 @@ void LLFloaterIMNearbyChat::onOpen(const LLSD& key) restoreFloater(); onCollapseToLine(this); } - showTranslationCheckbox(LLTranslate::isTranslationConfigured()); } // virtual diff --git a/indra/newview/llfloaterimsession.cpp b/indra/newview/llfloaterimsession.cpp index 41339620a5..a7698134f6 100644 --- a/indra/newview/llfloaterimsession.cpp +++ b/indra/newview/llfloaterimsession.cpp @@ -900,6 +900,7 @@ void LLFloaterIMSession::updateMessages() std::string from = msg["from"].asString(); std::string message = msg["message"].asString(); bool is_history = msg["is_history"].asBoolean(); + bool is_region_msg = msg["is_region_msg"].asBoolean(); LLChat chat; chat.mFromID = from_id; @@ -907,6 +908,10 @@ void LLFloaterIMSession::updateMessages() chat.mFromName = from; chat.mTimeStr = time; chat.mChatStyle = is_history ? CHAT_STYLE_HISTORY : chat.mChatStyle; + if (is_region_msg) + { + chat.mSourceType = CHAT_SOURCE_REGION; + } // process offer notification if (msg.has("notification_id")) diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp index 220f567ba9..0bda09c1a2 100644 --- a/indra/newview/llfloaterimsessiontab.cpp +++ b/indra/newview/llfloaterimsessiontab.cpp @@ -255,7 +255,6 @@ BOOL LLFloaterIMSessionTab::postBuild() mGearBtn = getChild("gear_btn"); mAddBtn = getChild("add_btn"); mVoiceButton = getChild("voice_call_btn"); - mTranslationCheckBox = getChild("translate_chat_checkbox_lp"); mParticipantListPanel = getChild("speakers_list_panel"); mRightPartPanel = getChild("right_part_holder"); @@ -813,8 +812,6 @@ void LLFloaterIMSessionTab::updateHeaderAndToolbar() mCloseBtn->setVisible(is_not_torn_off && !mIsNearbyChat); enableDisableCallBtn(); - - showTranslationCheckbox(); } void LLFloaterIMSessionTab::forceReshape() @@ -831,11 +828,6 @@ void LLFloaterIMSessionTab::reshapeChatLayoutPanel() mChatLayoutPanel->reshape(mChatLayoutPanel->getRect().getWidth(), mInputEditor->getRect().getHeight() + mInputEditorPad, FALSE); } -void LLFloaterIMSessionTab::showTranslationCheckbox(BOOL show) -{ - mTranslationCheckBox->setVisible(mIsNearbyChat && show); -} - // static void LLFloaterIMSessionTab::processChatHistoryStyleUpdate(bool clean_messages/* = false*/) { diff --git a/indra/newview/llfloaterimsessiontab.h b/indra/newview/llfloaterimsessiontab.h index ef15c4386f..1ca908315d 100644 --- a/indra/newview/llfloaterimsessiontab.h +++ b/indra/newview/llfloaterimsessiontab.h @@ -73,8 +73,6 @@ public: static LLFloaterIMSessionTab* findConversation(const LLUUID& uuid); static LLFloaterIMSessionTab* getConversation(const LLUUID& uuid); - // show/hide the translation check box - void showTranslationCheckbox(const BOOL visible = FALSE); bool isNearbyChat() {return mIsNearbyChat;} @@ -189,7 +187,6 @@ protected: LLButton* mGearBtn; LLButton* mAddBtn; LLButton* mVoiceButton; - LLUICtrl* mTranslationCheckBox; private: // Handling selection and contextual menu diff --git a/indra/newview/llfloateroutfitsnapshot.cpp b/indra/newview/llfloateroutfitsnapshot.cpp deleted file mode 100644 index 7513afed17..0000000000 --- a/indra/newview/llfloateroutfitsnapshot.cpp +++ /dev/null @@ -1,376 +0,0 @@ -/** - * @file llfloateroutfitsnapshot.cpp - * @brief Snapshot preview window for saving as an outfit thumbnail in visual outfit gallery - * - * $LicenseInfo:firstyear=2004&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2016, 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 "llfloatersnapshot.h" -#include "llfloateroutfitsnapshot.h" - -#include "llagent.h" -#include "llfloaterreg.h" -#include "llfloaterflickr.h" // Share to Flickr -#include "llimagefiltersmanager.h" -#include "llcheckboxctrl.h" -#include "llcombobox.h" -#include "llpostcard.h" -#include "llresmgr.h" // LLLocale -#include "llsdserialize.h" -#include "llsidetraypanelcontainer.h" -#include "llspinctrl.h" -#include "llviewercontrol.h" -#include "lltoolfocus.h" -#include "lltoolmgr.h" - -///---------------------------------------------------------------------------- -/// Local function declarations, constants, enums, and typedefs -///---------------------------------------------------------------------------- -LLOutfitSnapshotFloaterView* gOutfitSnapshotFloaterView = NULL; - -const S32 OUTFIT_SNAPSHOT_WIDTH = 256; -const S32 OUTFIT_SNAPSHOT_HEIGHT = 256; - -static LLDefaultChildRegistry::Register r("snapshot_outfit_floater_view"); - -///---------------------------------------------------------------------------- -/// Class LLFloaterOutfitSnapshot::Impl -///---------------------------------------------------------------------------- - -// virtual -LLPanelSnapshot* LLFloaterOutfitSnapshot::Impl::getActivePanel(LLFloaterSnapshotBase* floater, bool ok_if_not_found) -{ - LLPanel* panel = floater->getChild("panel_outfit_snapshot_inventory"); - LLPanelSnapshot* active_panel = dynamic_cast(panel); - if (!ok_if_not_found) - { - llassert_always(active_panel != NULL); - } - return active_panel; -} - -// virtual -LLSnapshotModel::ESnapshotFormat LLFloaterOutfitSnapshot::Impl::getImageFormat(LLFloaterSnapshotBase* floater) -{ - return LLSnapshotModel::SNAPSHOT_FORMAT_PNG; -} - -// virtual -LLSnapshotModel::ESnapshotLayerType LLFloaterOutfitSnapshot::Impl::getLayerType(LLFloaterSnapshotBase* floater) -{ - return LLSnapshotModel::SNAPSHOT_TYPE_COLOR; -} - -// This is the main function that keeps all the GUI controls in sync with the saved settings. -// It should be called anytime a setting is changed that could affect the controls. -// No other methods should be changing any of the controls directly except for helpers called by this method. -// The basic pattern for programmatically changing the GUI settings is to first set the -// appropriate saved settings and then call this method to sync the GUI with them. -// FIXME: The above comment seems obsolete now. -// virtual -void LLFloaterOutfitSnapshot::Impl::updateControls(LLFloaterSnapshotBase* floater) -{ - LLSnapshotModel::ESnapshotType shot_type = getActiveSnapshotType(floater); - LLSnapshotModel::ESnapshotFormat shot_format = (LLSnapshotModel::ESnapshotFormat)gSavedSettings.getS32("SnapshotFormat"); - LLSnapshotModel::ESnapshotLayerType layer_type = getLayerType(floater); - - LLSnapshotLivePreview* previewp = getPreviewView(); - BOOL got_snap = previewp && previewp->getSnapshotUpToDate(); - - // *TODO: Separate maximum size for Web images from postcards - LL_DEBUGS() << "Is snapshot up-to-date? " << got_snap << LL_ENDL; - - LLLocale locale(LLLocale::USER_LOCALE); - std::string bytes_string; - if (got_snap) - { - LLResMgr::getInstance()->getIntegerString(bytes_string, (previewp->getDataSize()) >> 10); - } - - // Update displayed image resolution. - LLTextBox* image_res_tb = floater->getChild("image_res_text"); - image_res_tb->setVisible(got_snap); - if (got_snap) - { - image_res_tb->setTextArg("[WIDTH]", llformat("%d", previewp->getEncodedImageWidth())); - image_res_tb->setTextArg("[HEIGHT]", llformat("%d", previewp->getEncodedImageHeight())); - } - - floater->getChild("file_size_label")->setTextArg("[SIZE]", got_snap ? bytes_string : floater->getString("unknown")); - floater->getChild("file_size_label")->setColor(LLUIColorTable::instance().getColor("LabelTextColor")); - - updateResolution(floater); - - if (previewp) - { - previewp->setSnapshotType(shot_type); - previewp->setSnapshotFormat(shot_format); - previewp->setSnapshotBufferType(layer_type); - } - - LLPanelSnapshot* current_panel = Impl::getActivePanel(floater); - if (current_panel) - { - LLSD info; - info["have-snapshot"] = got_snap; - current_panel->updateControls(info); - } - LL_DEBUGS() << "finished updating controls" << LL_ENDL; -} - -// virtual -std::string LLFloaterOutfitSnapshot::Impl::getSnapshotPanelPrefix() -{ - return "panel_outfit_snapshot_"; -} - -// Show/hide upload status message. -// virtual -void LLFloaterOutfitSnapshot::Impl::setFinished(bool finished, bool ok, const std::string& msg) -{ - mFloater->setSuccessLabelPanelVisible(finished && ok); - mFloater->setFailureLabelPanelVisible(finished && !ok); - - if (finished) - { - LLUICtrl* finished_lbl = mFloater->getChild(ok ? "succeeded_lbl" : "failed_lbl"); - std::string result_text = mFloater->getString(msg + "_" + (ok ? "succeeded_str" : "failed_str")); - finished_lbl->setValue(result_text); - - LLPanel* snapshot_panel = mFloater->getChild("panel_outfit_snapshot_inventory"); - snapshot_panel->onOpen(LLSD()); - } -} - -void LLFloaterOutfitSnapshot::Impl::updateResolution(void* data) -{ - LLFloaterOutfitSnapshot *view = (LLFloaterOutfitSnapshot *)data; - - if (!view) - { - llassert(view); - return; - } - - S32 width = OUTFIT_SNAPSHOT_WIDTH; - S32 height = OUTFIT_SNAPSHOT_HEIGHT; - - LLSnapshotLivePreview* previewp = getPreviewView(); - if (previewp) - { - S32 original_width = 0, original_height = 0; - previewp->getSize(original_width, original_height); - - if (gSavedSettings.getBOOL("RenderUIInSnapshot") || gSavedSettings.getBOOL("RenderHUDInSnapshot")) - { //clamp snapshot resolution to window size when showing UI or HUD in snapshot - width = llmin(width, gViewerWindow->getWindowWidthRaw()); - height = llmin(height, gViewerWindow->getWindowHeightRaw()); - } - - - llassert(width > 0 && height > 0); - - // use the resolution from the selected pre-canned drop-down choice - LL_DEBUGS() << "Setting preview res selected from combo: " << width << "x" << height << LL_ENDL; - previewp->setSize(width, height); - - if (original_width != width || original_height != height) - { - // hide old preview as the aspect ratio could be wrong - checkAutoSnapshot(previewp, FALSE); - LL_DEBUGS() << "updating thumbnail" << LL_ENDL; - previewp->updateSnapshot(TRUE); - } - } -} - -///---------------------------------------------------------------------------- -/// Class LLFloaterOutfitSnapshot -///---------------------------------------------------------------------------- - -// Default constructor -LLFloaterOutfitSnapshot::LLFloaterOutfitSnapshot(const LLSD& key) -: LLFloaterSnapshotBase(key), -mOutfitGallery(NULL) -{ - impl = new Impl(this); -} - -LLFloaterOutfitSnapshot::~LLFloaterOutfitSnapshot() -{ -} - -// virtual -BOOL LLFloaterOutfitSnapshot::postBuild() -{ - mRefreshBtn = getChild("new_snapshot_btn"); - childSetAction("new_snapshot_btn", ImplBase::onClickNewSnapshot, this); - mRefreshLabel = getChild("refresh_lbl"); - mSucceessLblPanel = getChild("succeeded_panel"); - mFailureLblPanel = getChild("failed_panel"); - - childSetCommitCallback("ui_check", ImplBase::onClickUICheck, this); - getChild("ui_check")->setValue(gSavedSettings.getBOOL("RenderUIInSnapshot")); - - childSetCommitCallback("hud_check", ImplBase::onClickHUDCheck, this); - getChild("hud_check")->setValue(gSavedSettings.getBOOL("RenderHUDInSnapshot")); - - // FIRE-15853: HUDs, interface or L$ balance checkbox don't update actual screenshot image - childSetCommitCallback("currency_check", ImplBase::onClickCurrencyCheck, this); - - getChild("freeze_frame_check")->setValue(gSavedSettings.getBOOL("UseFreezeFrame")); - childSetCommitCallback("freeze_frame_check", ImplBase::onCommitFreezeFrame, this); - - getChild("auto_snapshot_check")->setValue(gSavedSettings.getBOOL("AutoSnapshot")); - childSetCommitCallback("auto_snapshot_check", ImplBase::onClickAutoSnap, this); - - getChild("retract_btn")->setCommitCallback(boost::bind(&LLFloaterOutfitSnapshot::onExtendFloater, this)); - getChild("extend_btn")->setCommitCallback(boost::bind(&LLFloaterOutfitSnapshot::onExtendFloater, this)); - - // Filters - LLComboBox* filterbox = getChild("filters_combobox"); - std::vector filter_list = LLImageFiltersManager::getInstance()->getFiltersList(); - for (U32 i = 0; i < filter_list.size(); i++) - { - filterbox->add(filter_list[i]); - } - childSetCommitCallback("filters_combobox", ImplBase::onClickFilter, this); - - mThumbnailPlaceholder = getChild("thumbnail_placeholder"); - - // create preview window - LLRect full_screen_rect = getRootView()->getRect(); - LLSnapshotLivePreview::Params p; - p.rect(full_screen_rect); - LLSnapshotLivePreview* previewp = new LLSnapshotLivePreview(p); - LLView* parent_view = gSnapshotFloaterView->getParent(); - - parent_view->removeChild(gSnapshotFloaterView); - // make sure preview is below snapshot floater - parent_view->addChild(previewp); - parent_view->addChild(gSnapshotFloaterView); - - //move snapshot floater to special purpose snapshotfloaterview - gFloaterView->removeChild(this); - gSnapshotFloaterView->addChild(this); - - impl->mPreviewHandle = previewp->getHandle(); - previewp->setContainer(this); - impl->updateControls(this); - impl->setAdvanced(gSavedSettings.getBOOL("AdvanceOutfitSnapshot")); - impl->updateLayout(this); - - previewp->mKeepAspectRatio = FALSE; - previewp->setThumbnailPlaceholderRect(getThumbnailPlaceholderRect()); - - return TRUE; -} - -// virtual -void LLFloaterOutfitSnapshot::onOpen(const LLSD& key) -{ - LLSnapshotLivePreview* preview = getPreviewView(); - if (preview) - { - LL_DEBUGS() << "opened, updating snapshot" << LL_ENDL; - preview->updateSnapshot(TRUE); - } - focusFirstItem(FALSE); - gSnapshotFloaterView->setEnabled(TRUE); - gSnapshotFloaterView->setVisible(TRUE); - gSnapshotFloaterView->adjustToFitScreen(this, FALSE); - - impl->updateControls(this); - impl->setAdvanced(gSavedSettings.getBOOL("AdvanceOutfitSnapshot")); - impl->updateLayout(this); - - LLPanel* snapshot_panel = getChild("panel_outfit_snapshot_inventory"); - snapshot_panel->onOpen(LLSD()); - postPanelSwitch(); - -} - -void LLFloaterOutfitSnapshot::onExtendFloater() -{ - impl->setAdvanced(gSavedSettings.getBOOL("AdvanceOutfitSnapshot")); -} - -// static -void LLFloaterOutfitSnapshot::update() -{ - LLFloaterOutfitSnapshot* inst = findInstance(); - if (inst != NULL) - { - inst->impl->updateLivePreview(); - } -} - - -// static -LLFloaterOutfitSnapshot* LLFloaterOutfitSnapshot::findInstance() -{ - return LLFloaterReg::findTypedInstance("outfit_snapshot"); -} - -// static -LLFloaterOutfitSnapshot* LLFloaterOutfitSnapshot::getInstance() -{ - return LLFloaterReg::getTypedInstance("outfit_snapshot"); -} - -// virtual -void LLFloaterOutfitSnapshot::saveTexture() -{ - LL_DEBUGS() << "saveTexture" << LL_ENDL; - - LLSnapshotLivePreview* previewp = getPreviewView(); - if (!previewp) - { - llassert(previewp != NULL); - return; - } - - if (mOutfitGallery) - { - mOutfitGallery->onBeforeOutfitSnapshotSave(); - } - previewp->saveTexture(TRUE, getOutfitID().asString()); - if (mOutfitGallery) - { - mOutfitGallery->onAfterOutfitSnapshotSave(); - } - closeFloater(); -} - -///---------------------------------------------------------------------------- -/// Class LLOutfitSnapshotFloaterView -///---------------------------------------------------------------------------- - -LLOutfitSnapshotFloaterView::LLOutfitSnapshotFloaterView(const Params& p) : LLFloaterView(p) -{ -} - -LLOutfitSnapshotFloaterView::~LLOutfitSnapshotFloaterView() -{ -} diff --git a/indra/newview/llfloateroutfitsnapshot.h b/indra/newview/llfloateroutfitsnapshot.h deleted file mode 100644 index bee386ec63..0000000000 --- a/indra/newview/llfloateroutfitsnapshot.h +++ /dev/null @@ -1,123 +0,0 @@ -/** - * @file llfloateroutfitsnapshot.h - * @brief Snapshot preview window for saving as an outfit thumbnail in visual outfit gallery - * - * $LicenseInfo:firstyear=2004&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2016, 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_LLFLOATEROUTFITSNAPSHOT_H -#define LL_LLFLOATEROUTFITSNAPSHOT_H - -#include "llfloater.h" -#include "llfloatersnapshot.h" -#include "lloutfitgallery.h" -#include "llsnapshotlivepreview.h" - -///---------------------------------------------------------------------------- -/// Class LLFloaterOutfitSnapshot -///---------------------------------------------------------------------------- - -class LLFloaterOutfitSnapshot : public LLFloaterSnapshotBase -{ - LOG_CLASS(LLFloaterOutfitSnapshot); - -public: - - LLFloaterOutfitSnapshot(const LLSD& key); - /*virtual*/ ~LLFloaterOutfitSnapshot(); - - /*virtual*/ BOOL postBuild(); - /*virtual*/ void onOpen(const LLSD& key); - - static void update(); - - void onExtendFloater(); - - static LLFloaterOutfitSnapshot* getInstance(); - static LLFloaterOutfitSnapshot* findInstance(); - /*virtual*/ void saveTexture(); - - const LLRect& getThumbnailPlaceholderRect() { return mThumbnailPlaceholder->getRect(); } - - void setOutfitID(LLUUID id) { mOutfitID = id; } - LLUUID getOutfitID() { return mOutfitID; } - void setGallery(LLOutfitGallery* gallery) { mOutfitGallery = gallery; } - - class Impl; - friend class Impl; -private: - - LLUUID mOutfitID; - LLOutfitGallery* mOutfitGallery; -}; - -///---------------------------------------------------------------------------- -/// Class LLFloaterOutfitSnapshot::Impl -///---------------------------------------------------------------------------- - -class LLFloaterOutfitSnapshot::Impl : public LLFloaterSnapshotBase::ImplBase -{ - LOG_CLASS(LLFloaterOutfitSnapshot::Impl); -public: - Impl(LLFloaterSnapshotBase* floater) - : LLFloaterSnapshotBase::ImplBase(floater) - {} - ~Impl() - {} - void updateResolution(void* data); - - static void onSnapshotUploadFinished(LLFloaterSnapshotBase* floater, bool status); - - /*virtual*/ LLPanelSnapshot* getActivePanel(LLFloaterSnapshotBase* floater, bool ok_if_not_found = true); - /*virtual*/ LLSnapshotModel::ESnapshotFormat getImageFormat(LLFloaterSnapshotBase* floater); - /*virtual*/ std::string getSnapshotPanelPrefix(); - - /*virtual*/ void updateControls(LLFloaterSnapshotBase* floater); - -private: - /*virtual*/ LLSnapshotModel::ESnapshotLayerType getLayerType(LLFloaterSnapshotBase* floater); - /*virtual*/ void setFinished(bool finished, bool ok = true, const std::string& msg = LLStringUtil::null); -}; - -///---------------------------------------------------------------------------- -/// Class LLOutfitSnapshotFloaterView -///---------------------------------------------------------------------------- - -class LLOutfitSnapshotFloaterView : public LLFloaterView -{ -public: - struct Params - : public LLInitParam::Block - { - }; - -protected: - LLOutfitSnapshotFloaterView(const Params& p); - friend class LLUICtrlFactory; - -public: - virtual ~LLOutfitSnapshotFloaterView(); -}; - -extern LLOutfitSnapshotFloaterView* gOutfitSnapshotFloaterView; - -#endif // LL_LLFLOATEROUTFITSNAPSHOT_H diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index facbf4fe2b..13e5e45068 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -932,6 +932,7 @@ void LLFloaterPreference::saveSettings() if (panel) panel->saveSettings(); } + saveIgnoredNotifications(); } void LLFloaterPreference::apply() @@ -1065,6 +1066,8 @@ void LLFloaterPreference::cancel() gSavedSettings.setString("PresetGraphicActive", mSavedGraphicsPreset); LLPresetsManager::getInstance()->triggerChangeSignal(); } + + restoreIgnoredNotifications(); } void LLFloaterPreference::onOpen(const LLSD& key) @@ -2479,6 +2482,10 @@ void LLFloaterPreference::onClickPreviewUISound(const LLSD& ui_sound_id) // } // // buildPopupLists(); +// if (!mFilterEdit->getText().empty()) +// { +// filterIgnorableNotifications(); +// } // } // void LLFloaterPreference::onClickDisablePopup() @@ -2494,6 +2501,10 @@ void LLFloaterPreference::onClickPreviewUISound(const LLSD& ui_sound_id) // } // // buildPopupLists(); +// if (!mFilterEdit->getText().empty()) +// { +// filterIgnorableNotifications(); +// } // } // @@ -4941,11 +4952,23 @@ void LLFloaterPreference::onUpdateFilterTerm(bool force) return; mSearchData->mRootTab->hightlightAndHide( seachValue ); + //filterIgnorableNotifications(); // Using different solution LLTabContainer *pRoot = getChild< LLTabContainer >( "pref core" ); if( pRoot ) pRoot->selectFirstTab(); } +void LLFloaterPreference::filterIgnorableNotifications() +{ + bool visible = getChildRef("enabled_popups").highlightMatchingItems(mFilterEdit->getValue()); + visible |= getChildRef("disabled_popups").highlightMatchingItems(mFilterEdit->getValue()); + + if (visible) + { + getChildRef("pref core").setTabVisibility(getChild("msgs"), true); + } +} + void collectChildren( LLView const *aView, ll::prefs::PanelDataPtr aParentPanel, ll::prefs::TabContainerDataPtr aParentTabContainer ) { if( !aView ) @@ -5035,6 +5058,31 @@ void LLFloaterPreference::collectSearchableItems() mSearchDataDirty = false; } +void LLFloaterPreference::saveIgnoredNotifications() +{ + for (LLNotifications::TemplateMap::const_iterator iter = LLNotifications::instance().templatesBegin(); + iter != LLNotifications::instance().templatesEnd(); + ++iter) + { + LLNotificationTemplatePtr templatep = iter->second; + LLNotificationFormPtr formp = templatep->mForm; + + LLNotificationForm::EIgnoreType ignore = formp->getIgnoreType(); + if (ignore <= LLNotificationForm::IGNORE_NO) + continue; + + mIgnorableNotifs[templatep->mName] = !formp->getIgnored(); + } +} + +void LLFloaterPreference::restoreIgnoredNotifications() +{ + for (std::map::iterator it = mIgnorableNotifs.begin(); it != mIgnorableNotifs.end(); ++it) + { + LLUI::getInstance()->mSettingGroups["ignores"]->setBOOL(it->first, it->second); + } +} + // [SL:KB] - Patch: Viewer-CrashReporting | Checked: 2010-11-16 (Catznip-2.6.0a) | Added: Catznip-2.4.0b static LLPanelInjector t_pref_crashreports("panel_preference_crashreports"); diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h index a85a1ee4d9..6aeaeb7af3 100644 --- a/indra/newview/llfloaterpreference.h +++ b/indra/newview/llfloaterpreference.h @@ -182,6 +182,9 @@ public: // cancel() can restore them. void saveSettings(); + void saveIgnoredNotifications(); + void restoreIgnoredNotifications(); + void setCacheLocation(const LLStringExplicit& location); // Sound cache void setSoundCacheLocation(const LLStringExplicit& location); @@ -326,6 +329,9 @@ private: void onUpdateFilterTerm( bool force = false ); void collectSearchableItems(); + void filterIgnorableNotifications(); + + std::map mIgnorableNotifs; // FIRE-19539 - Include the alert messages in Prefs>Notifications>Alerts in preference Search. LLScrollListCtrl* mPopupList; diff --git a/indra/newview/llfloatersimpleoutfitsnapshot.cpp b/indra/newview/llfloatersimpleoutfitsnapshot.cpp new file mode 100644 index 0000000000..bab2efbbd5 --- /dev/null +++ b/indra/newview/llfloatersimpleoutfitsnapshot.cpp @@ -0,0 +1,333 @@ +/** +* @file llfloatersimpleoutfitsnapshot.cpp +* @brief Snapshot preview window for saving as an outfit thumbnail in visual outfit gallery +* +* $LicenseInfo:firstyear=2022&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2022, 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 "llfloatersimpleoutfitsnapshot.h" + +#include "llfloaterreg.h" +#include "llimagefiltersmanager.h" +#include "llstatusbar.h" // can_afford_transaction() +#include "llnotificationsutil.h" +#include "llagentbenefits.h" +#include "llviewercontrol.h" + +LLSimpleOutfitSnapshotFloaterView* gSimpleOutfitSnapshotFloaterView = NULL; + +const S32 OUTFIT_SNAPSHOT_WIDTH = 256; +const S32 OUTFIT_SNAPSHOT_HEIGHT = 256; + +static LLDefaultChildRegistry::Register r("simple_snapshot_outfit_floater_view"); + +///---------------------------------------------------------------------------- +/// Class LLFloaterSimpleOutfitSnapshot::Impl +///---------------------------------------------------------------------------- + +LLSnapshotModel::ESnapshotFormat LLFloaterSimpleOutfitSnapshot::Impl::getImageFormat(LLFloaterSnapshotBase* floater) +{ + return LLSnapshotModel::SNAPSHOT_FORMAT_PNG; +} + +LLSnapshotModel::ESnapshotLayerType LLFloaterSimpleOutfitSnapshot::Impl::getLayerType(LLFloaterSnapshotBase* floater) +{ + return LLSnapshotModel::SNAPSHOT_TYPE_COLOR; +} + +void LLFloaterSimpleOutfitSnapshot::Impl::updateControls(LLFloaterSnapshotBase* floater) +{ + LLSnapshotLivePreview* previewp = getPreviewView(); + updateResolution(floater); + if (previewp) + { + previewp->setSnapshotType(LLSnapshotModel::ESnapshotType::SNAPSHOT_TEXTURE); + previewp->setSnapshotFormat(LLSnapshotModel::ESnapshotFormat::SNAPSHOT_FORMAT_PNG); + previewp->setSnapshotBufferType(LLSnapshotModel::ESnapshotLayerType::SNAPSHOT_TYPE_COLOR); + } +} + +std::string LLFloaterSimpleOutfitSnapshot::Impl::getSnapshotPanelPrefix() +{ + return "panel_outfit_snapshot_"; +} + +void LLFloaterSimpleOutfitSnapshot::Impl::updateResolution(void* data) +{ + LLFloaterSimpleOutfitSnapshot *view = (LLFloaterSimpleOutfitSnapshot *)data; + + if (!view) + { + llassert(view); + return; + } + + S32 width = OUTFIT_SNAPSHOT_WIDTH; + S32 height = OUTFIT_SNAPSHOT_HEIGHT; + + LLSnapshotLivePreview* previewp = getPreviewView(); + if (previewp) + { + S32 original_width = 0, original_height = 0; + previewp->getSize(original_width, original_height); + + if (gSavedSettings.getBOOL("RenderHUDInSnapshot")) + { //clamp snapshot resolution to window size when showing UI HUD in snapshot + width = llmin(width, gViewerWindow->getWindowWidthRaw()); + height = llmin(height, gViewerWindow->getWindowHeightRaw()); + } + + llassert(width > 0 && height > 0); + + previewp->setSize(width, height); + + if (original_width != width || original_height != height) + { + // hide old preview as the aspect ratio could be wrong + checkAutoSnapshot(previewp, FALSE); + previewp->updateSnapshot(TRUE); + } + } +} + +void LLFloaterSimpleOutfitSnapshot::Impl::setStatus(EStatus status, bool ok, const std::string& msg) +{ + switch (status) + { + case STATUS_READY: + mFloater->setCtrlsEnabled(true); + break; + case STATUS_WORKING: + mFloater->setCtrlsEnabled(false); + break; + case STATUS_FINISHED: + mFloater->setCtrlsEnabled(true); + break; + } + + mStatus = status; +} + +///----------------------------------------------------------------re------------ +/// Class LLFloaterSimpleOutfitSnapshot +///---------------------------------------------------------------------------- + +LLFloaterSimpleOutfitSnapshot::LLFloaterSimpleOutfitSnapshot(const LLSD& key) + : LLFloaterSnapshotBase(key), + mOutfitGallery(NULL) +{ + impl = new Impl(this); +} + +LLFloaterSimpleOutfitSnapshot::~LLFloaterSimpleOutfitSnapshot() +{ +} + +BOOL LLFloaterSimpleOutfitSnapshot::postBuild() +{ + getChild("save_btn")->setLabelArg("[UPLOAD_COST]", std::to_string(LLAgentBenefitsMgr::current().getTextureUploadCost())); + + childSetAction("new_snapshot_btn", ImplBase::onClickNewSnapshot, this); + childSetAction("save_btn", boost::bind(&LLFloaterSimpleOutfitSnapshot::onSend, this)); + childSetAction("cancel_btn", boost::bind(&LLFloaterSimpleOutfitSnapshot::onCancel, this)); + + mThumbnailPlaceholder = getChild("thumbnail_placeholder"); + + // create preview window + LLRect full_screen_rect = getRootView()->getRect(); + LLSnapshotLivePreview::Params p; + p.rect(full_screen_rect); + LLSnapshotLivePreview* previewp = new LLSnapshotLivePreview(p); + LLView* parent_view = gSnapshotFloaterView->getParent(); + + parent_view->removeChild(gSnapshotFloaterView); + // make sure preview is below snapshot floater + parent_view->addChild(previewp); + parent_view->addChild(gSnapshotFloaterView); + + //move snapshot floater to special purpose snapshotfloaterview + gFloaterView->removeChild(this); + gSnapshotFloaterView->addChild(this); + + impl->mPreviewHandle = previewp->getHandle(); + previewp->setContainer(this); + impl->updateControls(this); + impl->setAdvanced(true); + impl->setSkipReshaping(true); + + previewp->mKeepAspectRatio = FALSE; + previewp->setThumbnailPlaceholderRect(getThumbnailPlaceholderRect()); + previewp->setAllowRenderUI(false); + + return TRUE; +} +const S32 PREVIEW_OFFSET_X = 12; +const S32 PREVIEW_OFFSET_Y = 70; + +void LLFloaterSimpleOutfitSnapshot::draw() +{ + LLSnapshotLivePreview* previewp = getPreviewView(); + + if (previewp && (previewp->isSnapshotActive() || previewp->getThumbnailLock())) + { + // don't render snapshot window in snapshot, even if "show ui" is turned on + return; + } + + LLFloater::draw(); + + if (previewp && !isMinimized() && mThumbnailPlaceholder->getVisible()) + { + if(previewp->getThumbnailImage()) + { + bool working = impl->getStatus() == ImplBase::STATUS_WORKING; + const LLRect& thumbnail_rect = getThumbnailPlaceholderRect(); + const S32 thumbnail_w = previewp->getThumbnailWidth(); + const S32 thumbnail_h = previewp->getThumbnailHeight(); + + S32 offset_x = PREVIEW_OFFSET_X; + S32 offset_y = PREVIEW_OFFSET_Y; + + gGL.matrixMode(LLRender::MM_MODELVIEW); + // Apply floater transparency to the texture unless the floater is focused. + F32 alpha = getTransparencyType() == TT_ACTIVE ? 1.0f : getCurrentTransparency(); + LLColor4 color = working ? LLColor4::grey4 : LLColor4::white; + gl_draw_scaled_image(offset_x, offset_y, + thumbnail_w, thumbnail_h, + previewp->getThumbnailImage(), color % alpha); +#if LL_DARWIN + std::string alpha_color = getTransparencyType() == TT_ACTIVE ? "OutfitSnapshotMacMask" : "OutfitSnapshotMacMask2"; +#else + std::string alpha_color = getTransparencyType() == TT_ACTIVE ? "FloaterFocusBackgroundColor" : "DkGray"; +#endif + + previewp->drawPreviewRect(offset_x, offset_y, LLUIColorTable::instance().getColor(alpha_color)); + + gGL.pushUIMatrix(); + LLUI::translate((F32) thumbnail_rect.mLeft, (F32) thumbnail_rect.mBottom); + mThumbnailPlaceholder->draw(); + gGL.popUIMatrix(); + } + } + impl->updateLayout(this); +} + +void LLFloaterSimpleOutfitSnapshot::onOpen(const LLSD& key) +{ + LLSnapshotLivePreview* preview = getPreviewView(); + if (preview) + { + preview->updateSnapshot(TRUE); + } + focusFirstItem(FALSE); + gSnapshotFloaterView->setEnabled(TRUE); + gSnapshotFloaterView->setVisible(TRUE); + gSnapshotFloaterView->adjustToFitScreen(this, FALSE); + + impl->updateControls(this); + impl->setStatus(ImplBase::STATUS_READY); +} + +void LLFloaterSimpleOutfitSnapshot::onCancel() +{ + closeFloater(); +} + +void LLFloaterSimpleOutfitSnapshot::onSend() +{ + S32 expected_upload_cost = LLAgentBenefitsMgr::current().getTextureUploadCost(); + if (can_afford_transaction(expected_upload_cost)) + { + saveTexture(); + postSave(); + } + else + { + LLSD args; + args["COST"] = llformat("%d", expected_upload_cost); + LLNotificationsUtil::add("ErrorPhotoCannotAfford", args); + inventorySaveFailed(); + } +} + +void LLFloaterSimpleOutfitSnapshot::postSave() +{ + impl->setStatus(ImplBase::STATUS_WORKING); +} + +// static +void LLFloaterSimpleOutfitSnapshot::update() +{ + LLFloaterSimpleOutfitSnapshot* inst = findInstance(); + if (inst != NULL) + { + inst->impl->updateLivePreview(); + } +} + + +// static +LLFloaterSimpleOutfitSnapshot* LLFloaterSimpleOutfitSnapshot::findInstance() +{ + return LLFloaterReg::findTypedInstance("simple_outfit_snapshot"); +} + +// static +LLFloaterSimpleOutfitSnapshot* LLFloaterSimpleOutfitSnapshot::getInstance() +{ + return LLFloaterReg::getTypedInstance("simple_outfit_snapshot"); +} + +void LLFloaterSimpleOutfitSnapshot::saveTexture() +{ + LLSnapshotLivePreview* previewp = getPreviewView(); + if (!previewp) + { + llassert(previewp != NULL); + return; + } + + if (mOutfitGallery) + { + mOutfitGallery->onBeforeOutfitSnapshotSave(); + } + previewp->saveTexture(TRUE, getOutfitID().asString()); + if (mOutfitGallery) + { + mOutfitGallery->onAfterOutfitSnapshotSave(); + } + closeFloater(); +} + +///---------------------------------------------------------------------------- +/// Class LLSimpleOutfitSnapshotFloaterView +///---------------------------------------------------------------------------- + +LLSimpleOutfitSnapshotFloaterView::LLSimpleOutfitSnapshotFloaterView(const Params& p) : LLFloaterView(p) +{ +} + +LLSimpleOutfitSnapshotFloaterView::~LLSimpleOutfitSnapshotFloaterView() +{ +} diff --git a/indra/newview/llfloatersimpleoutfitsnapshot.h b/indra/newview/llfloatersimpleoutfitsnapshot.h new file mode 100644 index 0000000000..cc9a6c5d1e --- /dev/null +++ b/indra/newview/llfloatersimpleoutfitsnapshot.h @@ -0,0 +1,129 @@ +/** +* @file llfloatersimpleoutfitsnapshot.h +* @brief Snapshot preview window for saving as an outfit thumbnail in visual outfit gallery +* +* $LicenseInfo:firstyear=2022&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2022, 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_LLFLOATERSIMPLEOUTFITSNAPSHOT_H +#define LL_LLFLOATERSIMPLEOUTFITSNAPSHOT_H + +#include "llfloater.h" +#include "llfloatersnapshot.h" +#include "lloutfitgallery.h" +#include "llsnapshotlivepreview.h" + +///---------------------------------------------------------------------------- +/// Class LLFloaterSimpleOutfitSnapshot +///---------------------------------------------------------------------------- + +class LLFloaterSimpleOutfitSnapshot : public LLFloaterSnapshotBase +{ + LOG_CLASS(LLFloaterSimpleOutfitSnapshot); + +public: + + LLFloaterSimpleOutfitSnapshot(const LLSD& key); + ~LLFloaterSimpleOutfitSnapshot(); + + BOOL postBuild(); + void onOpen(const LLSD& key); + void draw(); + + static void update(); + + static LLFloaterSimpleOutfitSnapshot* getInstance(); + static LLFloaterSimpleOutfitSnapshot* findInstance(); + void saveTexture(); + + const LLRect& getThumbnailPlaceholderRect() { return mThumbnailPlaceholder->getRect(); } + + void setOutfitID(LLUUID id) { mOutfitID = id; } + LLUUID getOutfitID() { return mOutfitID; } + void setGallery(LLOutfitGallery* gallery) { mOutfitGallery = gallery; } + + void postSave(); + + class Impl; + friend class Impl; + +private: + void onSend(); + void onCancel(); + + LLUUID mOutfitID; + LLOutfitGallery* mOutfitGallery; +}; + +///---------------------------------------------------------------------------- +/// Class LLFloaterSimpleOutfitSnapshot::Impl +///---------------------------------------------------------------------------- + +class LLFloaterSimpleOutfitSnapshot::Impl : public LLFloaterSnapshotBase::ImplBase +{ + LOG_CLASS(LLFloaterSimpleOutfitSnapshot::Impl); +public: + Impl(LLFloaterSnapshotBase* floater) + : LLFloaterSnapshotBase::ImplBase(floater) + {} + ~Impl() + {} + void updateResolution(void* data); + + static void onSnapshotUploadFinished(LLFloaterSnapshotBase* floater, bool status); + + LLPanelSnapshot* getActivePanel(LLFloaterSnapshotBase* floater, bool ok_if_not_found = true) { return NULL; } + LLSnapshotModel::ESnapshotFormat getImageFormat(LLFloaterSnapshotBase* floater); + std::string getSnapshotPanelPrefix(); + + void updateControls(LLFloaterSnapshotBase* floater); + + void setStatus(EStatus status, bool ok = true, const std::string& msg = LLStringUtil::null); + +private: + LLSnapshotModel::ESnapshotLayerType getLayerType(LLFloaterSnapshotBase* floater); + void setFinished(bool finished, bool ok = true, const std::string& msg = LLStringUtil::null) {}; +}; + +///---------------------------------------------------------------------------- +/// Class LLSimpleOutfitSnapshotFloaterView +///---------------------------------------------------------------------------- + +class LLSimpleOutfitSnapshotFloaterView : public LLFloaterView +{ +public: + struct Params + : public LLInitParam::Block + { + }; + +protected: + LLSimpleOutfitSnapshotFloaterView(const Params& p); + friend class LLUICtrlFactory; + +public: + virtual ~LLSimpleOutfitSnapshotFloaterView(); +}; + +extern LLSimpleOutfitSnapshotFloaterView* gSimpleOutfitSnapshotFloaterView; + +#endif // LL_LLFLOATERSIMPLEOUTFITSNAPSHOT_H diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp index 8019e523db..10c2b79c1b 100644 --- a/indra/newview/llfloatersnapshot.cpp +++ b/indra/newview/llfloatersnapshot.cpp @@ -193,20 +193,28 @@ void LLFloaterSnapshotBase::ImplBase::updateLayout(LLFloaterSnapshotBase* floate //thumbnail_placeholder->reshape(panel_width, thumbnail_placeholder->getRect().getHeight()); //floaterp->getChild("image_res_text")->setVisible(advanced); //floaterp->getChild("file_size_label")->setVisible(advanced); - //if(!floaterp->isMinimized()) + //if (floaterp->hasChild("360_label", TRUE)) //{ - // floaterp->reshape(floater_width, floaterp->getRect().getHeight()); + // floaterp->getChild("360_label")->setVisible(mAdvanced); + //} + //if (!mSkipReshaping) + //{ + // thumbnail_placeholder->reshape(panel_width, thumbnail_placeholder->getRect().getHeight()); + // if (!floaterp->isMinimized()) + // { + // floaterp->reshape(floater_width, floaterp->getRect().getHeight()); + // } //} previewp->setFixedThumbnailSize(panel_width, 400); LLUICtrl* thumbnail_placeholder = floaterp->getChild("thumbnail_placeholder"); floaterp->getChild("image_res_text")->setVisible(mAdvanced); floaterp->getChild("file_size_label")->setVisible(mAdvanced); - if (floaterp->hasChild("360_label", TRUE)) - { - floaterp->getChild("360_label")->setVisible(mAdvanced); - } - if(!floaterp->isMinimized()) + if (floaterp->hasChild("360_label", TRUE)) + { + floaterp->getChild("360_label")->setVisible(mAdvanced); + } + if (!mSkipReshaping && !floaterp->isMinimized()) { LLView* controls_container = floaterp->getChild("controls_container"); if (mAdvanced) @@ -1388,7 +1396,7 @@ S32 LLFloaterSnapshotBase::notify(const LLSD& info) // The refresh button is initially hidden. We show it after the first update, // i.e. when preview appears. - if (!mRefreshBtn->getVisible()) + if (mRefreshBtn && !mRefreshBtn->getVisible()) { mRefreshBtn->setVisible(true); } diff --git a/indra/newview/llfloatersnapshot.h b/indra/newview/llfloatersnapshot.h index 5977cb9a57..79767774d7 100644 --- a/indra/newview/llfloatersnapshot.h +++ b/indra/newview/llfloatersnapshot.h @@ -59,9 +59,9 @@ public: const LLRect& getThumbnailPlaceholderRect() { return mThumbnailPlaceholder->getRect(); } - void setRefreshLabelVisible(bool value) { mRefreshLabel->setVisible(value); } - void setSuccessLabelPanelVisible(bool value) { mSucceessLblPanel->setVisible(value); } - void setFailureLabelPanelVisible(bool value) { mFailureLblPanel->setVisible(value); } + void setRefreshLabelVisible(bool value) { if (mRefreshLabel) mRefreshLabel->setVisible(value); } + void setSuccessLabelPanelVisible(bool value) { if (mSucceessLblPanel) mSucceessLblPanel->setVisible(value); } + void setFailureLabelPanelVisible(bool value) { if (mFailureLblPanel) mFailureLblPanel->setVisible(value); } void inventorySaveFailed(); class ImplBase; @@ -88,6 +88,7 @@ public: mLastToolset(NULL), mAspectRatioCheckOff(false), mNeedRefresh(false), + mSkipReshaping(false), mStatus(STATUS_READY), mFloater(floater) {} @@ -122,6 +123,7 @@ public: static BOOL updatePreviewList(bool initialized); void setAdvanced(bool advanced) { mAdvanced = advanced; } + void setSkipReshaping(bool skip) { mSkipReshaping = skip; } virtual LLSnapshotModel::ESnapshotLayerType getLayerType(LLFloaterSnapshotBase* floater) = 0; virtual void checkAutoSnapshot(LLSnapshotLivePreview* floater, BOOL update_thumbnail = FALSE); @@ -137,6 +139,7 @@ public: bool mAspectRatioCheckOff; bool mNeedRefresh; bool mAdvanced; + bool mSkipReshaping; EStatus mStatus; }; diff --git a/indra/newview/llfloatertranslationsettings.cpp b/indra/newview/llfloatertranslationsettings.cpp index a85e4efc45..6f11086c67 100644 --- a/indra/newview/llfloatertranslationsettings.cpp +++ b/indra/newview/llfloatertranslationsettings.cpp @@ -292,11 +292,6 @@ void LLFloaterTranslationSettings::onBtnOK() gSavedSettings.setString("TranslationService", getSelectedService()); gSavedSettings.setString("BingTranslateAPIKey", getEnteredBingKey()); gSavedSettings.setString("GoogleTranslateAPIKey", getEnteredGoogleKey()); - // [FS communication UI] - //(LLFloaterReg::getTypedInstance("nearby_chat"))-> - // showTranslationCheckbox(LLTranslate::isTranslationConfigured()); - (LLFloaterReg::getTypedInstance("fs_nearby_chat"))-> - enableTranslationButton(LLTranslate::isTranslationConfigured()); - // [FS communication UI] + closeFloater(false); } diff --git a/indra/newview/llgroupactions.cpp b/indra/newview/llgroupactions.cpp index 7e414dd24f..dac8a034e5 100644 --- a/indra/newview/llgroupactions.cpp +++ b/indra/newview/llgroupactions.cpp @@ -203,8 +203,7 @@ public: virtual void processGroupData() = 0; protected: LLUUID mGroupId; -private: - bool mRequestProcessed; + bool mRequestProcessed; }; class LLFetchLeaveGroupData: public LLFetchGroupMemberData @@ -217,6 +216,22 @@ public: { LLGroupActions::processLeaveGroupDataResponse(mGroupId); } + void changed(LLGroupChange gc) + { + if (gc == GC_PROPERTIES && !mRequestProcessed) + { + LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupId); + if (!gdatap) + { + LL_WARNS() << "GroupData was NULL" << LL_ENDL; + } + else + { + processGroupData(); + mRequestProcessed = true; + } + } + } }; LLFetchLeaveGroupData* gFetchLeaveGroupData = NULL; diff --git a/indra/newview/llimprocessing.cpp b/indra/newview/llimprocessing.cpp index 6fc0c0374f..bef574e9e5 100644 --- a/indra/newview/llimprocessing.cpp +++ b/indra/newview/llimprocessing.cpp @@ -58,6 +58,7 @@ #include "llviewerwindow.h" #include "llviewerregion.h" #include "llvoavatarself.h" +#include "llworld.h" #include "boost/lexical_cast.hpp" @@ -876,7 +877,7 @@ void LLIMProcessing::processNewMessage(LLUUID from_id, parent_estate_id, region_id, position, - true, + false, false, keyword_alert_performed); @@ -1006,6 +1007,15 @@ void LLIMProcessing::processNewMessage(LLUUID from_id, buffer = saved + message; + bool region_message = false; + if (region_id.isNull()) + { + LLViewerRegion* regionp = LLWorld::instance().getRegionFromID(from_id); + if (regionp) + { + region_message = true; + } + } gIMMgr->addMessage( session_id, from_id, @@ -1017,7 +1027,7 @@ void LLIMProcessing::processNewMessage(LLUUID from_id, parent_estate_id, region_id, position, - true, + region_message, false, keyword_alert_performed); } @@ -1694,8 +1704,7 @@ void LLIMProcessing::processNewMessage(LLUUID from_id, IM_SESSION_INVITE, parent_estate_id, region_id, - position, - true); + position); } else { @@ -1732,7 +1741,7 @@ void LLIMProcessing::processNewMessage(LLUUID from_id, parent_estate_id, region_id, position, - true, + false, false, keyword_alert_performed); } diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index 9e0b540813..4c380d320e 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -902,7 +902,7 @@ void LLIMModel::LLIMSession::sessionInitReplyReceived(const LLUUID& new_session_ } } -void LLIMModel::LLIMSession::addMessage(const std::string& from, const LLUUID& from_id, const std::string& utf8_text, const std::string& time, const bool is_history) +void LLIMModel::LLIMSession::addMessage(const std::string& from, const LLUUID& from_id, const std::string& utf8_text, const std::string& time, const bool is_history, bool is_region_msg) { LLSD message; message["from"] = from; @@ -911,6 +911,7 @@ void LLIMModel::LLIMSession::addMessage(const std::string& from, const LLUUID& f message["time"] = time; message["index"] = (LLSD::Integer)mMsgs.size(); message["is_history"] = is_history; + message["is_region_msg"] = is_region_msg; LL_DEBUGS("UIUsage") << "addMessage " << " from " << from << " from_id " << from_id << " utf8_text " << utf8_text << " time " << time << " is_history " << is_history << " session mType " << mType << LL_ENDL; if (from_id == gAgent.getID()) @@ -1316,8 +1317,8 @@ void LLIMModel::sendNoUnreadMessages(const LLUUID& session_id) } // Added is_announcement parameter -//bool LLIMModel::addToHistory(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, const std::string& utf8_text) { -bool LLIMModel::addToHistory(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, const std::string& utf8_text, bool is_announcement /* = false */) { +//bool LLIMModel::addToHistory(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, const std::string& utf8_text, bool is_region_msg) { +bool LLIMModel::addToHistory(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, const std::string& utf8_text, bool is_region_msg, bool is_announcement /* = false */) { LLIMSession* session = findIMSession(session_id); @@ -1329,7 +1330,7 @@ bool LLIMModel::addToHistory(const LLUUID& session_id, const std::string& from, // Forward IM to nearby chat if wanted std::string timestr = LLLogChat::timestamp(false); - session->addMessage(from, from_id, utf8_text, timestr); //might want to add date separately + session->addMessage(from, from_id, utf8_text, timestr, is_region_msg); //might want to add date separately static LLCachedControl show_im_in_chat(gSavedSettings, "FSShowIMInChatHistory"); if (show_im_in_chat && !is_announcement) @@ -1401,11 +1402,11 @@ bool LLIMModel::proccessOnlineOfflineNotification( // Added is_announcement parameter //bool LLIMModel::addMessage(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, -// const std::string& utf8_text, bool log2file /* = true */) { +// const std::string& utf8_text, bool log2file, bool is_region_msg) { bool LLIMModel::addMessage(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, - const std::string& utf8_text, bool log2file /* = true */, bool is_announcement /* = false */, bool keyword_alert_performed /* = false */) { + const std::string& utf8_text, bool log2file, bool is_region_msg, bool is_announcement /* = false */, bool keyword_alert_performed /* = false */) { - LLIMSession* session = addMessageSilently(session_id, from, from_id, utf8_text, log2file, is_announcement); + LLIMSession* session = addMessageSilently(session_id, from, from_id, utf8_text, log2file, is_region_msg, is_announcement); if (!session) return false; //good place to add some1 to recent list @@ -1433,9 +1434,9 @@ bool LLIMModel::addMessage(const LLUUID& session_id, const std::string& from, co // Added is_announcement parameter //LLIMModel::LLIMSession* LLIMModel::addMessageSilently(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, -// const std::string& utf8_text, bool log2file /* = true */) +// const std::string& utf8_text, bool log2file, bool is_region_msg) LLIMModel::LLIMSession* LLIMModel::addMessageSilently(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, - const std::string& utf8_text, bool log2file /* = true */, bool is_announcement /* = false */) + const std::string& utf8_text, bool log2file, bool is_region_msg, bool is_announcement /* = false */) { LLIMSession* session = findIMSession(session_id); @@ -1451,7 +1452,7 @@ LLIMModel::LLIMSession* LLIMModel::addMessageSilently(const LLUUID& session_id, from_name = SYSTEM_FROM; } - addToHistory(session_id, from_name, from_id, utf8_text, is_announcement); + addToHistory(session_id, from_name, from_id, utf8_text, is_region_msg, is_announcement); if (log2file && !is_announcement) { logToFile(getHistoryFileName(session_id), from_name, from_id, utf8_text); @@ -2950,7 +2951,7 @@ void LLIMMgr::addMessage( U32 parent_estate_id, const LLUUID& region_id, const LLVector3& position, - bool link_name, // If this is true, then we insert the name and link it to a profile + bool is_region_msg, bool is_announcement, // Special parameter indicating announcements bool keyword_alert_performed) // Pass info if keyword alert has been performed { @@ -3080,7 +3081,7 @@ void LLIMMgr::addMessage( //<< "*** region_id: " << region_id << std::endl //<< "*** position: " << position << std::endl; - LLIMModel::instance().addMessage(new_session_id, from, other_participant_id, bonus_info.str()); + LLIMModel::instance().addMessage(new_session_id, from, other_participant_id, bonus_info.str(), true, is_region_msg); } // Logically it would make more sense to reject the session sooner, in another area of the @@ -3206,8 +3207,8 @@ void LLIMMgr::addMessage( if (!LLMuteList::getInstance()->isMuted(other_participant_id, LLMute::flagTextChat) && !skip_message) { // Added is_announcement parameter - //LLIMModel::instance().addMessage(new_session_id, from, other_participant_id, msg); - LLIMModel::instance().addMessage(new_session_id, from, other_participant_id, msg, true, is_announcement, keyword_alert_performed); + //LLIMModel::instance().addMessage(new_session_id, from, other_participant_id, msg, true, is_region_msg); + LLIMModel::instance().addMessage(new_session_id, from, other_participant_id, msg, true, is_region_msg, is_announcement, keyword_alert_performed); } // Open conversation floater if offline messages are present @@ -4464,8 +4465,8 @@ public: IM_SESSION_INVITE, message_params["parent_estate_id"].asInteger(), message_params["region_id"].asUUID(), - ll_vector3_from_sd(message_params["position"]), - true); + ll_vector3_from_sd(message_params["position"])); + // FIRE-9762 - OK, return here if we must! #ifdef OPENSIM if (is_opensim && from_id == gAgentID) diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h index d9bd010e3c..d6ee0394a9 100644 --- a/indra/newview/llimview.h +++ b/indra/newview/llimview.h @@ -90,7 +90,7 @@ public: void sessionInitReplyReceived(const LLUUID& new_session_id); void addMessagesFromHistory(const std::list& history); - void addMessage(const std::string& from, const LLUUID& from_id, const std::string& utf8_text, const std::string& time, const bool is_history = false); + void addMessage(const std::string& from, const LLUUID& from_id, const std::string& utf8_text, const std::string& time, const bool is_history = false, bool is_region_msg = false); void onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state, const LLVoiceChannel::EDirection& direction); /** @deprecated */ @@ -240,8 +240,8 @@ public: * It sends new message signal for each added message. */ // Added is_announcement parameter - //bool addMessage(const LLUUID& session_id, const std::string& from, const LLUUID& other_participant_id, const std::string& utf8_text, bool log2file = true); - bool addMessage(const LLUUID& session_id, const std::string& from, const LLUUID& other_participant_id, const std::string& utf8_text, bool log2file = true, bool is_announcement = false, bool keyword_alert_performed = false); + //bool addMessage(const LLUUID& session_id, const std::string& from, const LLUUID& other_participant_id, const std::string& utf8_text, bool log2file = true, bool is_region_msg = false); + bool addMessage(const LLUUID& session_id, const std::string& from, const LLUUID& other_participant_id, const std::string& utf8_text, bool log2file = true, bool is_region_msg = false, bool is_announcement = false, bool keyword_alert_performed = false); /** * Similar to addMessage(...) above but won't send a signal about a new message added @@ -250,7 +250,7 @@ public: //LLIMModel::LLIMSession* addMessageSilently(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, // const std::string& utf8_text, bool log2file = true); LLIMModel::LLIMSession* addMessageSilently(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, - const std::string& utf8_text, bool log2file = true, bool is_announcement = false); + const std::string& utf8_text, bool log2file = true, bool is_region_msg = false, bool is_announcement = false); /** * Add a system message to an IM Model @@ -331,8 +331,8 @@ private: * Add message to a list of message associated with session specified by session_id */ // Added is_announcement parameter - //bool addToHistory(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, const std::string& utf8_text); - bool addToHistory(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, const std::string& utf8_text, bool is_announcement = false); + //bool addToHistory(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, const std::string& utf8_text, bool is_region_msg = false); + bool addToHistory(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, const std::string& utf8_text, bool is_region_msg = false, bool is_announcement = false); }; class LLIMSessionObserver @@ -373,7 +373,7 @@ public: U32 parent_estate_id = 0, const LLUUID& region_id = LLUUID::null, const LLVector3& position = LLVector3::zero, - bool link_name = false, + bool is_region_msg = false, bool is_announcement = false, // Special parameter indicating announcement bool keyword_alert_performed = false // Pass info if keyword alert has been performed ); diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 98a31cb467..0dfadb63db 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -662,7 +662,7 @@ BOOL LLInvFVBridge::isClipboardPasteable() const if (cat) { LLFolderBridge cat_br(mInventoryPanel.get(), mRoot, item_id); - if (!cat_br.isItemCopyable()) + if (!cat_br.isItemCopyable(false)) return FALSE; // Skip to the next item in the clipboard continue; @@ -670,7 +670,7 @@ BOOL LLInvFVBridge::isClipboardPasteable() const // Each item must be copyable to be pastable LLItemBridge item_br(mInventoryPanel.get(), mRoot, item_id); - if (!item_br.isItemCopyable()) + if (!item_br.isItemCopyable(false)) { return FALSE; } @@ -702,6 +702,11 @@ BOOL LLInvFVBridge::isClipboardPasteableAsLink() const { return FALSE; } + + if (gInventory.isObjectDescendentOf(item->getUUID(), gInventory.getLibraryRootFolderID())) + { + return FALSE; + } } const LLViewerInventoryCategory *cat = model->getCategory(objects.at(i)); if (cat && LLFolderType::lookupIsProtectedType(cat->getPreferredType())) @@ -777,15 +782,15 @@ void hide_context_entries(LLMenuGL& menu, } bool found = false; - menuentry_vec_t::const_iterator itor2; - for (itor2 = entries_to_show.begin(); itor2 != entries_to_show.end(); ++itor2) - { - if (*itor2 == name) - { - found = true; - break; - } - } + + std::string myinput; + std::vector mylist{ "a", "b", "c" }; + + menuentry_vec_t::const_iterator itor2 = std::find(entries_to_show.begin(), entries_to_show.end(), name); + if (itor2 != entries_to_show.end()) + { + found = true; + } // Don't allow multiple separators in a row (e.g. such as if there are no items // between two separators). @@ -803,7 +808,21 @@ void hide_context_entries(LLMenuGL& menu, menu_item->setVisible(FALSE); } - menu_item->setEnabled(FALSE); + if (menu_item->getEnabled()) + { + // These should stay enabled unless specifically disabled + const menuentry_vec_t exceptions = { + "Detach From Yourself", + "Wearable And Object Wear", + "Wearable Add", + }; + + menuentry_vec_t::const_iterator itor2 = std::find(exceptions.begin(), exceptions.end(), name); + if (itor2 == exceptions.end()) + { + menu_item->setEnabled(FALSE); + } + } } else { @@ -956,7 +975,8 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id, disabled_items.push_back(std::string("Paste")); } - if (gSavedSettings.getBOOL("InventoryLinking") + static LLCachedControl inventory_linking(gSavedSettings, "InventoryLinking", true); + if (inventory_linking // Client LSL Bridge (also for #AO) && !isLockedFolder() // @@ -2284,7 +2304,8 @@ BOOL LLItemBridge::removeItem() // [SL:KB] - Patch: Inventory-Links | Checked: 2010-06-01 (Catznip-2.2.0a) | Added: Catznip-2.0.1a // Users move folders around and reuse links that way... if we know something has links then it's just bad not to warn them :| // [/SL:KB] -// if (!gSavedSettings.getBOOL("InventoryLinking")) +// static LLCachedControl inventory_linking(gSavedSettings, "InventoryLinking", true); +// if (!inventory_linking) { if (!item->getIsLinkType()) { @@ -2327,39 +2348,42 @@ BOOL LLItemBridge::confirmRemoveItem(const LLSD& notification, const LLSD& respo return FALSE; } -BOOL LLItemBridge::isItemCopyable() const +bool LLItemBridge::isItemCopyable(bool can_copy_as_link) const { - LLViewerInventoryItem* item = getItem(); - if (item) - { + LLViewerInventoryItem* item = getItem(); + if (!item) + { + return false; + } /* - // Can't copy worn objects. - // Worn objects are tied to their inworld conterparts - // Copy of modified worn object will return object with obsolete asset and inventory - if(get_is_item_worn(mUUID)) - { - return FALSE; - } + // Can't copy worn objects. + // Worn objects are tied to their inworld conterparts + // Copy of modified worn object will return object with obsolete asset and inventory + if (get_is_item_worn(mUUID)) + { + return false; + } */ // [SL:KB] - Patch: Inventory-Links | Checked: 2010-04-12 (Catznip-2.2.0a) | Added: Catznip-2.0.0a - // We'll allow copying a link if: - // - its target is available - // - it doesn't point to another link [see LLViewerInventoryItem::getLinkedItem() which returns NULL in that case] - if (item->getIsLinkType()) - { - return (NULL != item->getLinkedItem()); - } + // We'll allow copying a link if: + // - its target is available + // - it doesn't point to another link [see LLViewerInventoryItem::getLinkedItem() which returns NULL in that case] + if (item->getIsLinkType()) + { + return (NULL != item->getLinkedItem()); + } - // User can copy the item if: - // - the item (or its target in the case of a link) is "copy" - // - and/or if the item (or its target in the case of a link) has a linkable asset type - // NOTE: we do *not* want to return TRUE on everything like LL seems to do in SL-2.1.0 because not all types are "linkable" - return (item->getPermissions().allowCopyBy(gAgent.getID())); + // User can copy the item if: + // - the item (or its target in the case of a link) is "copy" + + // NOTE: we do *not* want to return TRUE on everything like LL seems to do in SL-2.1.0 because not all types are "linkable" + return (item->getPermissions().allowCopyBy(gAgent.getID())); // [/SL:KB] -// return item->getPermissions().allowCopyBy(gAgent.getID()) || gSavedSettings.getBOOL("InventoryLinking"); - } - return FALSE; +// static LLCachedControl inventory_linking(gSavedSettings, "InventoryLinking", true); +// return (can_copy_as_link && inventory_linking) +// || item->getPermissions().allowCopyBy(gAgent.getID()); + } // [SL:KB] - Patch: Inventory-Links | Checked: 2013-09-19 (Catznip-3.6) @@ -2606,7 +2630,7 @@ BOOL LLFolderBridge::isUpToDate() const return category->getVersion() != LLViewerInventoryCategory::VERSION_UNKNOWN; } -BOOL LLFolderBridge::isItemCopyable() const +bool LLFolderBridge::isItemCopyable(bool can_copy_as_link) const { // Folders are copyable if items in them are, recursively, copyable. @@ -2621,22 +2645,26 @@ BOOL LLFolderBridge::isItemCopyable() const { LLInventoryItem* item = *iter; LLItemBridge item_br(mInventoryPanel.get(), mRoot, item->getUUID()); - if (!item_br.isItemCopyable()) - return FALSE; -} + if (!item_br.isItemCopyable(false)) + { + return false; + } + } // Check the folders LLInventoryModel::cat_array_t cat_array_copy = *cat_array; for (LLInventoryModel::cat_array_t::iterator iter = cat_array_copy.begin(); iter != cat_array_copy.end(); iter++) -{ + { LLViewerInventoryCategory* category = *iter; LLFolderBridge cat_br(mInventoryPanel.get(), mRoot, category->getUUID()); - if (!cat_br.isItemCopyable()) - return FALSE; - } - - return TRUE; - } + if (!cat_br.isItemCopyable(false)) + { + return false; + } + } + + return true; +} // [SL:KB] - Patch: Inventory-Links | Checked: 2013-09-19 (Catznip-3.6) bool LLFolderBridge::isItemLinkable() const @@ -4167,6 +4195,7 @@ void LLFolderBridge::perform_pasteFromClipboard() LLInventoryObject *obj = model->getObject(item_id); if (obj) { + if (move_is_into_lost_and_found) { if (LLAssetType::AT_CATEGORY == obj->getType()) diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h index 7a78567dcc..8b9fbef569 100644 --- a/indra/newview/llinventorybridge.h +++ b/indra/newview/llinventorybridge.h @@ -120,7 +120,7 @@ public: //virtual BOOL removeItem() = 0; virtual void removeBatch(std::vector& batch); virtual void move(LLFolderViewModelItem* new_parent_bridge) {} - virtual BOOL isItemCopyable() const { return FALSE; } + virtual bool isItemCopyable(bool can_copy_as_link = true) const { return false; } // [SL:KB] - Patch: Inventory-Links | Checked: 2013-09-19 (Catznip-3.6) virtual bool isItemLinkable() const { return FALSE; } // [/SL:KB] @@ -260,7 +260,7 @@ public: virtual BOOL isItemRenameable() const; virtual BOOL renameItem(const std::string& new_name); virtual BOOL removeItem(); - virtual BOOL isItemCopyable() const; + virtual bool isItemCopyable(bool can_copy_as_link = true) const; // [SL:KB] - Patch: Inventory-Links | Checked: 2013-09-19 (Catznip-3.6) /*virtual*/ bool isItemLinkable() const; // [/SL:KB] @@ -336,7 +336,7 @@ public: virtual BOOL isItemRemovable() const; virtual BOOL isItemMovable() const ; virtual BOOL isUpToDate() const; - virtual BOOL isItemCopyable() const; + virtual bool isItemCopyable(bool can_copy_as_link = true) const; // [SL:KB] - Patch: Inventory-Links | Checked: 2013-09-19 (Catznip-3.6) /*virtual*/ bool isItemLinkable() const; // [/SL:KB] diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 4f2fbedc15..9526bb7048 100644 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -989,6 +989,9 @@ LLUUID create_folder_for_item(LLInventoryItem* item, const LLUUID& destFolderId) S32 depth_nesting_in_marketplace(LLUUID cur_uuid) { // Get the marketplace listings root, exit with -1 (i.e. not under the marketplace listings root) if none + // Todo: findCategoryUUIDForType is somewhat expensive with large + // flat root folders yet we use depth_nesting_in_marketplace at + // every turn, find a way to correctly cache this id. const LLUUID marketplace_listings_uuid = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false); if (marketplace_listings_uuid.isNull()) { @@ -1631,7 +1634,12 @@ void dump_trace(std::string& message, S32 depth, LLError::ELevel log_level) // This function does no deletion of listings but a mere audit and raises issues to the user (through the // optional callback cb). It also returns a boolean, true if things validate, false if issues are raised. // The only inventory changes that are done is to move and sort folders containing no-copy items to stock folders. -bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_t cb, bool fix_hierarchy, S32 depth) +bool validate_marketplacelistings( + LLInventoryCategory* cat, + validation_callback_t cb, + bool fix_hierarchy, + S32 depth, + bool notify_observers) { #if 0 // Used only for debug @@ -1697,7 +1705,7 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ LLUUID folder_uuid = gInventory.createNewCategory(parent_uuid, LLFolderType::FT_NONE, cat->getName()); LLInventoryCategory* new_cat = gInventory.getCategory(folder_uuid); gInventory.changeCategoryParent(viewer_cat, folder_uuid, false); - result &= validate_marketplacelistings(new_cat, cb, fix_hierarchy, depth + 1); + result &= validate_marketplacelistings(new_cat, cb, fix_hierarchy, depth + 1, notify_observers); return result; } else @@ -1867,7 +1875,10 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ // Next type update_marketplace_category(parent_uuid); update_marketplace_category(folder_uuid); - gInventory.notifyObservers(); + if (notify_observers) + { + gInventory.notifyObservers(); + } items_vector_it++; } } @@ -1881,7 +1892,7 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ { LLViewerInventoryCategory * viewer_cat = (LLViewerInventoryCategory *) (*iter); gInventory.changeCategoryParent(viewer_cat, parent_uuid, false); - result &= validate_marketplacelistings(viewer_cat, cb, fix_hierarchy, depth); + result &= validate_marketplacelistings(viewer_cat, cb, fix_hierarchy, depth, false); } } } @@ -1953,7 +1964,10 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ cb(message,depth,LLError::LEVEL_WARN); } gInventory.removeCategory(cat->getUUID()); - gInventory.notifyObservers(); + if (notify_observers) + { + gInventory.notifyObservers(); + } return result && !has_bad_items; } } @@ -1967,11 +1981,14 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ for (LLInventoryModel::cat_array_t::iterator iter = cat_array_copy.begin(); iter != cat_array_copy.end(); iter++) { LLInventoryCategory* category = *iter; - result &= validate_marketplacelistings(category, cb, fix_hierarchy, depth + 1); + result &= validate_marketplacelistings(category, cb, fix_hierarchy, depth + 1, false); } update_marketplace_category(cat->getUUID(), true, true); - gInventory.notifyObservers(); + if (notify_observers) + { + gInventory.notifyObservers(); + } return result && !has_bad_items; } @@ -2859,8 +2876,62 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root } std::set selected_uuid_set = LLAvatarActions::getInventorySelectedUUIDs(); + + // copy list of applicable items into a vector for bulk handling uuid_vec_t ids; - std::copy(selected_uuid_set.begin(), selected_uuid_set.end(), std::back_inserter(ids)); + if (action == "wear" || action == "wear_add") + { + const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH); + const LLUUID mp_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false); + std::copy_if(selected_uuid_set.begin(), + selected_uuid_set.end(), + std::back_inserter(ids), + [trash_id, mp_id](LLUUID id) + { + if (get_is_item_worn(id) + || LLAppearanceMgr::instance().getIsInCOF(id) + || gInventory.isObjectDescendentOf(id, trash_id)) + { + return false; + } + if (mp_id.notNull() && gInventory.isObjectDescendentOf(id, mp_id)) + { + return false; + } + LLInventoryObject* obj = (LLInventoryObject*)gInventory.getObject(id); + if (!obj) + { + return false; + } + if (obj->getIsLinkType() && gInventory.isObjectDescendentOf(obj->getLinkedUUID(), trash_id)) + { + return false; + } + if (obj->getIsLinkType() && LLAssetType::lookupIsLinkType(obj->getType())) + { + // missing + return false; + } + return true; + } + ); + } + else if (isRemoveAction(action)) + { + std::copy_if(selected_uuid_set.begin(), + selected_uuid_set.end(), + std::back_inserter(ids), + [](LLUUID id) + { + return get_is_item_worn(id); + } + ); + } + else + { + std::copy(selected_uuid_set.begin(), selected_uuid_set.end(), std::back_inserter(ids)); + } + // Check for actions that get handled in bulk if (action == "wear") { diff --git a/indra/newview/llinventoryfunctions.h b/indra/newview/llinventoryfunctions.h index 9be37e33f0..a99886385b 100644 --- a/indra/newview/llinventoryfunctions.h +++ b/indra/newview/llinventoryfunctions.h @@ -94,7 +94,7 @@ bool can_move_item_to_marketplace(const LLInventoryCategory* root_folder, LLInve bool can_move_folder_to_marketplace(const LLInventoryCategory* root_folder, LLInventoryCategory* dest_folder, LLInventoryCategory* inv_cat, std::string& tooltip_msg, S32 bundle_size = 1, bool check_items = true, bool from_paste = false); bool move_item_to_marketplacelistings(LLInventoryItem* inv_item, LLUUID dest_folder, bool copy = false); bool move_folder_to_marketplacelistings(LLInventoryCategory* inv_cat, const LLUUID& dest_folder, bool copy = false, bool move_no_copy_items = false); -bool validate_marketplacelistings(LLInventoryCategory* inv_cat, validation_callback_t cb = NULL, bool fix_hierarchy = true, S32 depth = -1); +bool validate_marketplacelistings(LLInventoryCategory* inv_cat, validation_callback_t cb = NULL, bool fix_hierarchy = true, S32 depth = -1, bool notify_observers = true); S32 depth_nesting_in_marketplace(LLUUID cur_uuid); LLUUID nested_parent_id(LLUUID cur_uuid, S32 depth); S32 compute_stock_count(LLUUID cat_uuid, bool force_count = false); diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index 9a3932401b..d44553e478 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -2038,9 +2038,13 @@ void LLInventoryModel::addChangedMask(U32 mask, const LLUUID& referent) mChangedItemIDs.insert(referent); } - // Fix me: From DD-81, probably shouldn't be here, instead - // should be somewhere in an observer - update_marketplace_category(referent, false); + if (mask != LLInventoryObserver::LABEL) + { + // Fix me: From DD-81, probably shouldn't be here, instead + // should be somewhere in an observer or in + // LLMarketplaceInventoryObserver::onIdleProcessQueue + update_marketplace_category(referent, false); + } if (mask & LLInventoryObserver::ADD) { diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp index c4ebcfe40c..09fa993fc6 100644 --- a/indra/newview/llmarketplacefunctions.cpp +++ b/indra/newview/llmarketplacefunctions.cpp @@ -30,6 +30,7 @@ #include "llagent.h" #include "llbufferstream.h" +#include "llcallbacklist.h" #include "llinventoryfunctions.h" #include "llinventoryobserver.h" #include "llnotificationsutil.h" @@ -606,20 +607,67 @@ public: LLMarketplaceInventoryObserver() {} virtual ~LLMarketplaceInventoryObserver() {} virtual void changed(U32 mask); + +private: + static void onIdleProcessQueue(void *userdata); + + // doesn't hold just marketplace related ids + static std::set sAddQueue; + static std::set sStructureQueue; + static bool sProcessingQueue; }; +std::set LLMarketplaceInventoryObserver::sAddQueue; +std::set LLMarketplaceInventoryObserver::sStructureQueue; +bool LLMarketplaceInventoryObserver::sProcessingQueue = false; + void LLMarketplaceInventoryObserver::changed(U32 mask) { - // When things are added to the marketplace, we might need to re-validate and fix the containing listings - if (mask & LLInventoryObserver::ADD) + if (mask & LLInventoryObserver::ADD && LLMarketplaceData::instance().hasValidationWaiting()) { + // When things are added to the marketplace, we might need to re-validate and fix the containing listings + // just add whole list even if it contains items and non-marketplace folders const std::set& changed_items = gInventory.getChangedIDs(); - - std::set::const_iterator id_it = changed_items.begin(); - std::set::const_iterator id_end = changed_items.end(); + sAddQueue.insert(changed_items.begin(), changed_items.end()); + } + + if (mask & (LLInventoryObserver::INTERNAL | LLInventoryObserver::STRUCTURE)) + { + // When things are changed in the inventory, this can trigger a host of changes in the marketplace listings folder: + // * stock counts changing : no copy items coming in and out will change the stock count on folders + // * version and listing folders : moving those might invalidate the marketplace data itself + // Since we should cannot raise inventory change while the observer is called (the list will be cleared + // once observers are called) we need to raise a flag in the inventory to signal that things have been dirtied. + const std::set& changed_items = gInventory.getChangedIDs(); + sStructureQueue.insert(changed_items.begin(), changed_items.end()); + } + + if (!sProcessingQueue && (!sAddQueue.empty() || !sStructureQueue.empty())) + { + gIdleCallbacks.addFunction(onIdleProcessQueue, NULL); + // can do without sProcessingQueue, but it's usufull for simplicity and reliability + sProcessingQueue = true; + } +} + +void LLMarketplaceInventoryObserver::onIdleProcessQueue(void *userdata) +{ + U64 start_time = LLTimer::getTotalTime(); // microseconds + const U64 MAX_PROCESSING_TIME = 1000; + U64 stop_time = start_time + MAX_PROCESSING_TIME; + + if (!sAddQueue.empty()) + { + // Make a copy of sAddQueue since decrementValidationWaiting + // can theoretically add more items + std::set add_queue(sAddQueue); + sAddQueue.clear(); + + std::set::const_iterator id_it = add_queue.begin(); + std::set::const_iterator id_end = add_queue.end(); // First, count the number of items in this list... S32 count = 0; - for (;id_it != id_end; ++id_it) + for (; id_it != id_end; ++id_it) { LLInventoryObject* obj = gInventory.getObject(*id_it); if (obj && (LLAssetType::AT_CATEGORY != obj->getType())) @@ -630,56 +678,58 @@ void LLMarketplaceInventoryObserver::changed(U32 mask) // Then, decrement the folders of that amount // Note that of all of those, only one folder will be a listing folder (if at all). // The other will be ignored by the decrement method. - id_it = changed_items.begin(); - for (;id_it != id_end; ++id_it) + id_it = add_queue.begin(); + for (; id_it != id_end; ++id_it) { LLInventoryObject* obj = gInventory.getObject(*id_it); if (obj && (LLAssetType::AT_CATEGORY == obj->getType())) { - LLMarketplaceData::instance().decrementValidationWaiting(obj->getUUID(),count); + // can trigger notifyObservers + LLMarketplaceData::instance().decrementValidationWaiting(obj->getUUID(), count); } } - } - - // When things are changed in the inventory, this can trigger a host of changes in the marketplace listings folder: - // * stock counts changing : no copy items coming in and out will change the stock count on folders - // * version and listing folders : moving those might invalidate the marketplace data itself - // Since we should cannot raise inventory change while the observer is called (the list will be cleared - // once observers are called) we need to raise a flag in the inventory to signal that things have been dirtied. - - if (mask & (LLInventoryObserver::INTERNAL | LLInventoryObserver::STRUCTURE)) - { - const std::set& changed_items = gInventory.getChangedIDs(); - - std::set::const_iterator id_it = changed_items.begin(); - std::set::const_iterator id_end = changed_items.end(); - for (;id_it != id_end; ++id_it) + } + + while (!sStructureQueue.empty() && LLTimer::getTotalTime() < stop_time) + { + std::set::const_iterator id_it = sStructureQueue.begin(); + LLInventoryObject* obj = gInventory.getObject(*id_it); + if (obj) { - LLInventoryObject* obj = gInventory.getObject(*id_it); - if (obj) + if (LLAssetType::AT_CATEGORY == obj->getType()) { - if (LLAssetType::AT_CATEGORY == obj->getType()) + // If it's a folder known to the marketplace, let's check it's in proper shape + if (LLMarketplaceData::instance().isListed(*id_it) || LLMarketplaceData::instance().isVersionFolder(*id_it)) { - // If it's a folder known to the marketplace, let's check it's in proper shape - if (LLMarketplaceData::instance().isListed(*id_it) || LLMarketplaceData::instance().isVersionFolder(*id_it)) - { - LLInventoryCategory* cat = (LLInventoryCategory*)(obj); - validate_marketplacelistings(cat); - } + LLInventoryCategory* cat = (LLInventoryCategory*)(obj); + // can trigger notifyObservers + // can cause more structural changes + validate_marketplacelistings(cat); } - else + } + else + { + // If it's not a category, it's an item... + LLInventoryItem* item = (LLInventoryItem*)(obj); + // If it's a no copy item, we may need to update the label count of marketplace listings + if (!item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID(), gAgent.getGroupID())) { - // If it's not a category, it's an item... - LLInventoryItem* item = (LLInventoryItem*)(obj); - // If it's a no copy item, we may need to update the label count of marketplace listings - if (!item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID(), gAgent.getGroupID())) - { - LLMarketplaceData::instance().setDirtyCount(); - } + LLMarketplaceData::instance().setDirtyCount(); } } } - } + + // sStructureQueue could have been modified in validate_marketplacelistings + // adding items does not invalidate existing iterator + sStructureQueue.erase(id_it); + } + + if (LLApp::isExiting() || (sAddQueue.empty() && sStructureQueue.empty())) + { + // Nothing to do anymore + gIdleCallbacks.deleteFunction(onIdleProcessQueue, NULL); + sProcessingQueue = false; + } } // Tuple == Item diff --git a/indra/newview/llmarketplacefunctions.h b/indra/newview/llmarketplacefunctions.h index 088507d850..24fdc5e0ad 100644 --- a/indra/newview/llmarketplacefunctions.h +++ b/indra/newview/llmarketplacefunctions.h @@ -242,6 +242,7 @@ public: void setUpdating(const LLUUID& folder_id, bool isUpdating); // Used to decide when to run a validation on listing folders + bool hasValidationWaiting() { return mValidationWaitingList.size() > 0; } void setValidationWaiting(const LLUUID& folder_id, S32 count); void decrementValidationWaiting(const LLUUID& folder_id, S32 count = 1); diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp index 75b2307b5e..4b9f177eca 100644 --- a/indra/newview/lloutfitgallery.cpp +++ b/indra/newview/lloutfitgallery.cpp @@ -41,7 +41,7 @@ #include "llfilepicker.h" #include "llfloaterperms.h" #include "llfloaterreg.h" -#include "llfloateroutfitsnapshot.h" +#include "llfloatersimpleoutfitsnapshot.h" #include "llimagedimensionsinfo.h" #include "llinventoryfunctions.h" #include "llinventorymodel.h" @@ -1386,8 +1386,8 @@ void LLOutfitGallery::onSelectPhoto(LLUUID selected_outfit_id) void LLOutfitGallery::onTakeSnapshot(LLUUID selected_outfit_id) { - LLFloaterReg::toggleInstanceOrBringToFront("outfit_snapshot"); - LLFloaterOutfitSnapshot* snapshot_floater = LLFloaterOutfitSnapshot::getInstance(); + LLFloaterReg::toggleInstanceOrBringToFront("simple_outfit_snapshot"); + LLFloaterSimpleOutfitSnapshot* snapshot_floater = LLFloaterSimpleOutfitSnapshot::getInstance(); if (snapshot_floater) { snapshot_floater->setOutfitID(selected_outfit_id); diff --git a/indra/newview/llpanelmediasettingsgeneral.cpp b/indra/newview/llpanelmediasettingsgeneral.cpp index e1818cc68b..416857bd30 100644 --- a/indra/newview/llpanelmediasettingsgeneral.cpp +++ b/indra/newview/llpanelmediasettingsgeneral.cpp @@ -454,7 +454,8 @@ bool LLPanelMediaSettingsGeneral::navigateHomeSelectedFace(bool only_if_current_ LLViewerMedia::getInstance()->getMediaImplFromTextureID(object->getTE(face)->getMediaData()->getMediaID()); if(media_impl) { - media_impl->navigateHome(); + media_impl->setPriority(LLPluginClassMedia::PRIORITY_NORMAL); + media_impl->navigateHome(); return true; } } diff --git a/indra/newview/llpanelobject.cpp b/indra/newview/llpanelobject.cpp index a183a98ca5..1bb133734b 100644 --- a/indra/newview/llpanelobject.cpp +++ b/indra/newview/llpanelobject.cpp @@ -111,6 +111,9 @@ enum { MI_HOLE_COUNT }; +// Defined in llviewerjointattachment.h +//const F32 MAX_ATTACHMENT_DIST = 3.5f; // meters + //static const std::string LEGACY_FULLBRIGHT_DESC =LLTrans::getString("Fullbright"); BOOL LLPanelObject::postBuild() @@ -2261,12 +2264,7 @@ void LLPanelObject::sendPosition(BOOL btn_down) // Building spin controls for attachments LLVector3d new_pos_global; - if (mObject->isAttachment()) - { - newpos.clamp(LLVector3(-MAX_ATTACHMENT_DIST,-MAX_ATTACHMENT_DIST,-MAX_ATTACHMENT_DIST),LLVector3(MAX_ATTACHMENT_DIST,MAX_ATTACHMENT_DIST,MAX_ATTACHMENT_DIST)); - } - // Building spin controls for attachments - else + if (!mObject->isAttachment()) { // Clamp the Z height const F32 height = newpos.mV[VZ]; @@ -2301,6 +2299,16 @@ void LLPanelObject::sendPosition(BOOL btn_down) // won't get dumped by the simulator. new_pos_global = regionp->getPosGlobalFromRegion(newpos); } + else + { + if (newpos.length() > MAX_ATTACHMENT_DIST) + { + newpos.clampLength(MAX_ATTACHMENT_DIST); + mCtrlPosX->set(newpos.mV[VX]); + mCtrlPosY->set(newpos.mV[VY]); + mCtrlPosZ->set(newpos.mV[VZ]); + } + } // Building spin controls for attachments // partly copied from llmaniptranslate.cpp to get the positioning right @@ -2878,9 +2886,13 @@ void LLPanelObject::onPastePos() if (!mObject->isAttachment()) { F32 max_width = regionp->getWidth(); // meters - mClipboardPos.mV[VX] = llclamp( mClipboardPos.mV[VX], 0.f, max_width); - mClipboardPos.mV[VY] = llclamp( mClipboardPos.mV[VY], 0.f, max_width); - //height will get properly clammed by sendPosition + mClipboardPos.mV[VX] = llclamp(mClipboardPos.mV[VX], 0.f, max_width); + mClipboardPos.mV[VY] = llclamp(mClipboardPos.mV[VY], 0.f, max_width); + //height will get properly clamped by sendPosition + } + else + { + mClipboardPos.clampLength(MAX_ATTACHMENT_DIST); } mCtrlPosX->set( mClipboardPos.mV[VX] ); diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp index 587b2c8691..d4dea894b7 100644 --- a/indra/newview/llpanelobjectinventory.cpp +++ b/indra/newview/llpanelobjectinventory.cpp @@ -137,7 +137,7 @@ public: virtual BOOL removeItem(); virtual void removeBatch(std::vector& batch); virtual void move(LLFolderViewModelItem* parent_listener); - virtual BOOL isItemCopyable() const; + virtual bool isItemCopyable(bool can_copy_as_link = true) const; virtual BOOL copyToClipboard() const; virtual BOOL cutToClipboard(); virtual BOOL isClipboardPasteable() const; @@ -495,10 +495,10 @@ void LLTaskInvFVBridge::move(LLFolderViewModelItem* parent_listener) { } -BOOL LLTaskInvFVBridge::isItemCopyable() const +bool LLTaskInvFVBridge::isItemCopyable(bool can_link) const { LLInventoryItem* item = findItem(); - if(!item) return FALSE; + if(!item) return false; return gAgent.allowOperation(PERM_COPY, item->getPermissions(), GP_OBJECT_MANIPULATE); } diff --git a/indra/newview/llpanelpresetscamerapulldown.cpp b/indra/newview/llpanelpresetscamerapulldown.cpp index b1cbbe7931..3adcc18b9e 100644 --- a/indra/newview/llpanelpresetscamerapulldown.cpp +++ b/indra/newview/llpanelpresetscamerapulldown.cpp @@ -128,7 +128,10 @@ void LLPanelPresetsCameraPulldown::onRowClick(const LLSD& user_data) LL_DEBUGS() << "selected '" << name << "'" << LL_ENDL; LLFloaterCamera::switchToPreset(name); - setVisible(FALSE); + // Scroll grabbed focus, drop it to prevent selection of parent menu + setFocus(FALSE); + + setVisible(FALSE); } else { diff --git a/indra/newview/llpanelpresetspulldown.cpp b/indra/newview/llpanelpresetspulldown.cpp index 7f1b2aba0f..e59ec12529 100644 --- a/indra/newview/llpanelpresetspulldown.cpp +++ b/indra/newview/llpanelpresetspulldown.cpp @@ -120,6 +120,9 @@ void LLPanelPresetsPulldown::onRowClick(const LLSD& user_data) LL_DEBUGS() << "selected '" << name << "'" << LL_ENDL; LLPresetsManager::getInstance()->loadPreset(PRESETS_GRAPHIC, name); + // Scroll grabbed focus, drop it to prevent selection of parent menu + setFocus(FALSE); + setVisible(FALSE); } else diff --git a/indra/newview/llpanelpulldown.cpp b/indra/newview/llpanelpulldown.cpp index 4de6ee8182..075278f44c 100644 --- a/indra/newview/llpanelpulldown.cpp +++ b/indra/newview/llpanelpulldown.cpp @@ -51,6 +51,7 @@ void LLPanelPulldown::onMouseEnter(S32 x, S32 y, MASK mask) /*virtual*/ void LLPanelPulldown::onTopLost() { + setFocus(FALSE); // drop focus to prevent transfer to parent setVisible(FALSE); } @@ -113,6 +114,7 @@ void LLPanelPulldown::draw() if (alpha == 0.f) { + setFocus(FALSE); // drop focus to prevent transfer to parent setVisible(FALSE); } } diff --git a/indra/newview/llscripteditor.cpp b/indra/newview/llscripteditor.cpp index f10e263437..4b71be92d9 100644 --- a/indra/newview/llscripteditor.cpp +++ b/indra/newview/llscripteditor.cpp @@ -223,82 +223,8 @@ void LLScriptEditor::drawSelectionBackground() // Draw selection even if we don't have keyboard focus for search/replace if( hasSelection() && !mLineInfoList.empty()) { - std::vector selection_rects; - - S32 selection_left = llmin( mSelectionStart, mSelectionEnd ); - S32 selection_right = llmax( mSelectionStart, mSelectionEnd ); - - // Skip through the lines we aren't drawing. - LLRect content_display_rect = getVisibleDocumentRect(); - - // binary search for line that starts before top of visible buffer - line_list_t::const_iterator line_iter = std::lower_bound(mLineInfoList.begin(), mLineInfoList.end(), content_display_rect.mTop, LLTextBase::compare_bottom()); - line_list_t::const_iterator end_iter = std::upper_bound(mLineInfoList.begin(), mLineInfoList.end(), content_display_rect.mBottom, LLTextBase::compare_top()); - - bool done = false; - - // Find the coordinates of the selected area - for (;line_iter != end_iter && !done; ++line_iter) - { - // is selection visible on this line? - if (line_iter->mDocIndexEnd > selection_left && line_iter->mDocIndexStart < selection_right) - { - segment_set_t::iterator segment_iter; - S32 segment_offset; - getSegmentAndOffset(line_iter->mDocIndexStart, &segment_iter, &segment_offset); - - LLRect selection_rect; - selection_rect.mLeft = line_iter->mRect.mLeft; - selection_rect.mRight = line_iter->mRect.mLeft; - selection_rect.mBottom = line_iter->mRect.mBottom; - selection_rect.mTop = line_iter->mRect.mTop; - - for(;segment_iter != mSegments.end(); ++segment_iter, segment_offset = 0) - { - LLTextSegmentPtr segmentp = *segment_iter; - - S32 segment_line_start = segmentp->getStart() + segment_offset; - S32 segment_line_end = llmin(segmentp->getEnd(), line_iter->mDocIndexEnd); - - if (segment_line_start > segment_line_end) break; - - S32 segment_width = 0; - S32 segment_height = 0; - - // if selection after beginning of segment - if(selection_left >= segment_line_start) - { - S32 num_chars = llmin(selection_left, segment_line_end) - segment_line_start; - segmentp->getDimensions(segment_offset, num_chars, segment_width, segment_height); - selection_rect.mLeft += segment_width; - } - - // if selection_right == segment_line_end then that means we are the first character of the next segment - // or first character of the next line, in either case we want to add the length of the current segment - // to the selection rectangle and continue. - // if selection right > segment_line_end then selection spans end of current segment... - if (selection_right >= segment_line_end) - { - // extend selection slightly beyond end of line - // to indicate selection of newline character (use "n" character to determine width) - S32 num_chars = segment_line_end - segment_line_start; - segmentp->getDimensions(segment_offset, num_chars, segment_width, segment_height); - selection_rect.mRight += segment_width; - } - // else if selection ends on current segment... - else - { - S32 num_chars = selection_right - segment_line_start; - segmentp->getDimensions(segment_offset, num_chars, segment_width, segment_height); - selection_rect.mRight += segment_width; - - break; - } - } - selection_rects.push_back(selection_rect); - } - } - + std::vector selection_rects = getSelctionRects(); + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); const LLColor4& color = mReadOnly ? mReadOnlyFgColor : mFgColor; F32 alpha = hasFocus() ? 0.7f : 0.3f; @@ -308,6 +234,7 @@ void LLScriptEditor::drawSelectionBackground() (1.f + color.mV[VGREEN]) * 0.5f, (1.f + color.mV[VBLUE]) * 0.5f, alpha); + LLRect content_display_rect = getVisibleDocumentRect(); for (std::vector::iterator rect_it = selection_rects.begin(); rect_it != selection_rects.end(); diff --git a/indra/newview/llsnapshotlivepreview.cpp b/indra/newview/llsnapshotlivepreview.cpp index 1100ac1bb2..b0769e9d8e 100644 --- a/indra/newview/llsnapshotlivepreview.cpp +++ b/indra/newview/llsnapshotlivepreview.cpp @@ -238,7 +238,7 @@ bool LLSnapshotLivePreview::setSnapshotQuality(S32 quality, bool set_by_user) return false; } -void LLSnapshotLivePreview::drawPreviewRect(S32 offset_x, S32 offset_y) +void LLSnapshotLivePreview::drawPreviewRect(S32 offset_x, S32 offset_y, LLColor4 alpha_color) { F32 line_width ; glGetFloatv(GL_LINE_WIDTH, &line_width) ; @@ -251,7 +251,6 @@ void LLSnapshotLivePreview::drawPreviewRect(S32 offset_x, S32 offset_y) //draw four alpha rectangles to cover areas outside of the snapshot image if(!mKeepAspectRatio) { - LLColor4 alpha_color(0.5f, 0.5f, 0.5f, 0.8f) ; S32 dwl = 0, dwr = 0 ; if(mThumbnailWidth > mPreviewRect.getWidth()) { diff --git a/indra/newview/llsnapshotlivepreview.h b/indra/newview/llsnapshotlivepreview.h index 54b71af20c..ab7ae266cd 100644 --- a/indra/newview/llsnapshotlivepreview.h +++ b/indra/newview/llsnapshotlivepreview.h @@ -115,7 +115,7 @@ public: BOOL setThumbnailImageSize() ; void generateThumbnailImage(BOOL force_update = FALSE) ; void resetThumbnailImage() { mThumbnailImage = NULL ; } - void drawPreviewRect(S32 offset_x, S32 offset_y) ; + void drawPreviewRect(S32 offset_x, S32 offset_y, LLColor4 alpha_color = LLColor4(0.5f, 0.5f, 0.5f, 0.8f)); void prepareFreezeFrame(); LLViewerTexture* getBigThumbnailImage(); diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index ff0c4f3681..5310b96fa1 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -238,6 +238,7 @@ #include "fsfloaterimcontainer.h" #include "fsfloaternearbychat.h" #include "fsfloatersearch.h" +#include "fsfloaterstreamtitle.h" #include "fsfloaterwearablefavorites.h" #include "fslslbridge.h" #include "fsradar.h" @@ -1951,9 +1952,6 @@ bool idle_startup() // Initialize classes w/graphics stuff. // LLViewerStatsRecorder::instance(); // Since textures work in threads - gTextureList.doPrefetchImages(); - display_startup(); - LLSurface::initClasses(); display_startup(); @@ -2101,6 +2099,15 @@ bool idle_startup() if (STATE_SEED_CAP_GRANTED == LLStartUp::getStartupState()) { display_startup(); + + // These textures are not warrantied to be cached, so needs + // to hapen with caps granted + gTextureList.doPrefetchImages(); + + // will init images, should be done with caps, but before gSky.init() + LLEnvironment::getInstance()->initSingleton(); + + display_startup(); update_texture_fetch(); display_startup(); @@ -3425,8 +3432,10 @@ void use_circuit_callback(void**, S32 result) void register_viewer_callbacks(LLMessageSystem* msg) { msg->setHandlerFuncFast(_PREHASH_LayerData, process_layer_data ); + // OpenSim compatibility msg->setHandlerFuncFast(_PREHASH_ImageData, LLViewerTextureList::receiveImageHeader ); msg->setHandlerFuncFast(_PREHASH_ImagePacket, LLViewerTextureList::receiveImagePacket ); + // msg->setHandlerFuncFast(_PREHASH_ObjectUpdate, process_object_update ); msg->setHandlerFunc("ObjectUpdateCompressed", process_compressed_object_update ); msg->setHandlerFunc("ObjectUpdateCached", process_cached_object_update ); @@ -3847,6 +3856,7 @@ void reset_login() gAgentWearables.cleanup(); gAgentCamera.cleanup(); gAgent.cleanup(); + gSky.cleanup(); // mVOSkyp is an inworld object. LLWorld::getInstance()->resetClass(); if ( gViewerWindow ) @@ -3883,7 +3893,8 @@ void LLStartUp::multimediaInit() display_startup(); // Also initialise the stream titles. - new StreamTitleDisplay(); + StreamTitleDisplay::instance(); + FSStreamTitleManager::instance(); } void LLStartUp::fontInit() diff --git a/indra/newview/llsurfacepatch.cpp b/indra/newview/llsurfacepatch.cpp index a3480fdb10..0e745d6cff 100644 --- a/indra/newview/llsurfacepatch.cpp +++ b/indra/newview/llsurfacepatch.cpp @@ -844,7 +844,7 @@ BOOL LLSurfacePatch::updateTexture() { mVObjp->dirtyGeom(); gPipeline.markGLRebuild(mVObjp); - return TRUE; + return !mSTexUpdate; } } } diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp index 26a70697c6..b52d4f37ab 100644 --- a/indra/newview/lltexturecache.cpp +++ b/indra/newview/lltexturecache.cpp @@ -1670,6 +1670,12 @@ void LLTextureCache::purgeAllTextures(bool purge_directories) { gDirUtilp->deleteFilesInDir(dirname, mask); } +#if LL_WINDOWS + // Texture cache can be large and can take a while to remove + // assure OS that processes is alive and not hanging + MSG msg; + PeekMessage(&msg, 0, 0, 0, PM_NOREMOVE | PM_NOYIELD); +#endif } // Only delete folder if it actually exist if (LLFile::isdir(mTexturesDirName)) diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index db6de505a6..54d1a861ce 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -63,6 +63,7 @@ #include "llhttpretrypolicy.h" #include "fsassetblacklist.h" //For Asset blacklist #include "llviewermenu.h" +#include "llviewernetwork.h" // OpenSim compatibility bool LLTextureFetchDebugger::sDebuggerEnabled = false ; @@ -284,7 +285,7 @@ static const char* e_state_name[] = "LOAD_FROM_TEXTURE_CACHE", "CACHE_POST", "LOAD_FROM_NETWORK", - "LOAD_FROM_SIMULATOR", + "LOAD_FROM_SIMULATOR", // OpenSim compatibility "WAIT_HTTP_RESOURCE", "WAIT_HTTP_RESOURCE2", "SEND_HTTP_REQ", @@ -458,7 +459,7 @@ public: LOAD_FROM_TEXTURE_CACHE, CACHE_POST, LOAD_FROM_NETWORK, - LOAD_FROM_SIMULATOR, + LOAD_FROM_SIMULATOR, // OpenSim compatibility WAIT_HTTP_RESOURCE, // Waiting for HTTP resources WAIT_HTTP_RESOURCE2, // Waiting for HTTP resources SEND_HTTP_REQ, // Commit to sending as HTTP @@ -499,8 +500,10 @@ private: // Locks: Mw void clearPackets(); + // OpenSim compatibility // Locks: Mw void setupPacketData(); + // // Locks: Mw (ctor invokes without lock) U32 calcWorkPriority(); @@ -509,8 +512,10 @@ private: void removeFromCache(); // Threads: Ttf + // OpenSim compatibility // Locks: Mw bool processSimulatorPackets(); + // // Threads: Ttf bool writeToCacheComplete(); @@ -615,7 +620,7 @@ private: BOOL mInLocalCache; BOOL mInCache; bool mCanUseHTTP, - mCanUseNET ; //can get from asset server. + mCanUseNET ; //can get from asset server. // OpenSim compatibility S32 mRetryAttempt; S32 mActiveCount; LLCore::HttpStatus mGetStatus; @@ -887,7 +892,7 @@ const char* sStateDescs[] = { "LOAD_FROM_TEXTURE_CACHE", "CACHE_POST", "LOAD_FROM_NETWORK", - "LOAD_FROM_SIMULATOR", + "LOAD_FROM_SIMULATOR", // OpenSim compatibility "WAIT_HTTP_RESOURCE", "WAIT_HTTP_RESOURCE2", "SEND_HTTP_REQ", @@ -899,7 +904,7 @@ const char* sStateDescs[] = { "DONE" }; -const std::set LOGGED_STATES = { LLTextureFetchWorker::LOAD_FROM_TEXTURE_CACHE, LLTextureFetchWorker::LOAD_FROM_NETWORK, LLTextureFetchWorker::LOAD_FROM_SIMULATOR, +const std::set LOGGED_STATES = { LLTextureFetchWorker::LOAD_FROM_TEXTURE_CACHE, LLTextureFetchWorker::LOAD_FROM_NETWORK, LLTextureFetchWorker::LOAD_FROM_SIMULATOR, // OpenSim compatibility LLTextureFetchWorker::WAIT_HTTP_REQ, LLTextureFetchWorker::DECODE_IMAGE_UPDATE, LLTextureFetchWorker::WAIT_ON_WRITE }; // static @@ -974,8 +979,9 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher, mResourceWaitCount(0U), mFetchRetryPolicy(10.0,3600.0,2.0,10) { - mCanUseNET = mUrl.empty() ; - + // OpenSim compatibility + mCanUseNET = !LLGridManager::instance().isInSecondLife() && mUrl.empty() ; + calcWorkPriority(); mType = host.isOk() ? LLImageBase::TYPE_AVATAR_BAKE : LLImageBase::TYPE_NORMAL; // LL_INFOS(LOG_TXT) << "Create: " << mID << " mHost:" << host << " Discard=" << discard << LL_ENDL; @@ -1039,6 +1045,7 @@ void LLTextureFetchWorker::clearPackets() mFirstPacket = 0; } +// OpenSim compatibility // Locks: Mw void LLTextureFetchWorker::setupPacketData() { @@ -1071,6 +1078,7 @@ void LLTextureFetchWorker::setupPacketData() } } } +// // Locks: Mw (ctor invokes without lock) U32 LLTextureFetchWorker::calcWorkPriority() @@ -1179,13 +1187,19 @@ bool LLTextureFetchWorker::doWork(S32 param) if(mImagePriority < F_ALMOST_ZERO) { + // OpenSim compatibility + //if (mState == INIT || mState == LOAD_FROM_NETWORK) if (mState == INIT || mState == LOAD_FROM_NETWORK || mState == LOAD_FROM_SIMULATOR) + // { LL_DEBUGS(LOG_TXT) << mID << " abort: mImagePriority < F_ALMOST_ZERO" << LL_ENDL; return true; // abort } } + // OpenSim compatibility + //if(mState > CACHE_POST && !mCanUseHTTP) if(mState > CACHE_POST && !mCanUseNET && !mCanUseHTTP) + // { //nowhere to get data, abort. LL_WARNS(LOG_TXT) << mID << " abort, nowhere to get data" << LL_ENDL; @@ -1401,10 +1415,14 @@ bool LLTextureFetchWorker::doWork(S32 param) // { LLViewerRegion* region = NULL; - if (mHost.isInvalid()) - region = gAgent.getRegion(); - else - region = LLWorld::getInstance()->getRegion(mHost); + if (mHost.isInvalid()) + { + region = gAgent.getRegion(); + } + else if (LLWorld::instanceExists()) + { + region = LLWorld::getInstance()->getRegion(mHost); + } if (region) { @@ -1422,7 +1440,7 @@ bool LLTextureFetchWorker::doWork(S32 param) LL_WARNS(LOG_TXT) << "trying to seek a non-default texture on the sim. Bad!" << LL_ENDL; } setUrl(http_url + "/?texture_id=" + mID.asString().c_str()); - LL_DEBUGS(LOG_TXT) << "Texture URL: " << mUrl << LL_ENDL; + LL_WARNS(LOG_TXT) << "Texture URL: " << mUrl << LL_ENDL; mWriteToCacheState = CAN_WRITE ; //because this texture has a fixed texture id. } else @@ -1454,6 +1472,7 @@ bool LLTextureFetchWorker::doWork(S32 param) } // don't return, fall through to next state } + // OpenSim compatibility else if (mSentRequest == UNSENT && mCanUseNET) { // Add this to the network queue and sit here. @@ -1468,19 +1487,14 @@ bool LLTextureFetchWorker::doWork(S32 param) return false; } + // else { - // Shouldn't need to do anything here - //llassert_always(mFetcher->mNetworkQueue.find(mID) != mFetcher->mNetworkQueue.end()); - // Make certain this is in the network queue - //mFetcher->addToNetworkQueue(this); - //recordTextureStart(false); - //setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); - return false; } } - + + // OpenSim compatibility if (mState == LOAD_FROM_SIMULATOR) { if (mFormattedImage.isNull()) @@ -1531,6 +1545,7 @@ bool LLTextureFetchWorker::doWork(S32 param) } return false; } + // if (mState == WAIT_HTTP_RESOURCE) { @@ -1574,7 +1589,7 @@ bool LLTextureFetchWorker::doWork(S32 param) return true; // abort } - mFetcher->removeFromNetworkQueue(this, false); + mFetcher->removeFromNetworkQueue(this, false); // OpenSim compatibility S32 cur_size = 0; if (mFormattedImage.notNull()) @@ -1722,6 +1737,7 @@ bool LLTextureFetchWorker::doWork(S32 param) return true; } + // OpenSim compatibility // roll back to try UDP if (mCanUseNET) { @@ -1732,6 +1748,7 @@ bool LLTextureFetchWorker::doWork(S32 param) releaseHttpSemaphore(); return false; } + // } else if (http_service_unavail == mGetStatus) { @@ -2299,7 +2316,7 @@ void LLTextureFetchWorker::removeFromCache() } } - +// OpenSim compatibility ////////////////////////////////////////////////////////////////////////////// // Threads: Ttf @@ -2362,6 +2379,7 @@ bool LLTextureFetchWorker::processSimulatorPackets() } return false; } +// ////////////////////////////////////////////////////////////////////////////// @@ -2836,6 +2854,7 @@ bool LLTextureFetch::createRequest(FTType f_type, const std::string& url, const } +// OpenSim compatibility // Threads: T* (but Ttf in practice) // protected @@ -2869,6 +2888,7 @@ void LLTextureFetch::removeFromNetworkQueue(LLTextureFetchWorker* worker, bool c mCancelQueue[worker->mHost].insert(worker->mID); } } // -Mfnq +// // Threads: T* // @@ -2903,7 +2923,7 @@ void LLTextureFetch::deleteRequest(const LLUUID& id, bool cancel) unlockQueue(); // -Mfq llassert_always(erased_1 > 0) ; - removeFromNetworkQueue(worker, cancel); + removeFromNetworkQueue(worker, cancel); // OpenSim compatibility llassert_always(!(worker->getFlags(LLWorkerClass::WCF_DELETE_REQUESTED))) ; worker->scheduleDelete(); @@ -2931,7 +2951,7 @@ void LLTextureFetch::removeRequest(LLTextureFetchWorker* worker, bool cancel) unlockQueue(); // -Mfq llassert_always(erased_1 > 0) ; - removeFromNetworkQueue(worker, cancel); + removeFromNetworkQueue(worker, cancel); // OpenSim compatibility llassert_always(!(worker->getFlags(LLWorkerClass::WCF_DELETE_REQUESTED))) ; worker->scheduleDelete(); @@ -3220,6 +3240,7 @@ S32 LLTextureFetch::update(F32 max_time_ms) S32 res = LLWorkerThread::update(max_time_ms); + // OpenSim compatibility if (!mDebugPause) { // this is the startup state when send_complete_agent_movement() message is sent. @@ -3230,6 +3251,7 @@ S32 LLTextureFetch::update(F32 max_time_ms) sendRequestListToSimulators(); } } + // if (!mThreaded) { @@ -3319,6 +3341,7 @@ void LLTextureFetch::threadedUpdate() #endif } +// OpenSim compatibility ////////////////////////////////////////////////////////////////////////////// // Threads: Tmain @@ -3514,6 +3537,7 @@ void LLTextureFetch::sendRequestListToSimulators() } } // -Mfnq } +// ////////////////////////////////////////////////////////////////////////////// @@ -3579,6 +3603,7 @@ void LLTextureFetchWorker::setState(e_state new_state) mState = new_state; } +// OpenSim compatibility // Threads: T* bool LLTextureFetch::receiveImageHeader(const LLHost& host, const LLUUID& id, U8 codec, U16 packets, U32 totalbytes, U16 data_size, U8* data) @@ -3710,6 +3735,7 @@ bool LLTextureFetch::receiveImagePacket(const LLHost& host, const LLUUID& id, U1 return res; } +// ////////////////////////////////////////////////////////////////////////////// @@ -3749,6 +3775,8 @@ S32 LLTextureFetch::getFetchState(const LLUUID& id, F32& data_progress_p, F32& r request_dtime = worker->mRequestedDeltaTimer.getElapsedTimeF32(); if (worker->mFileSize > 0) { + // OpenSim compatibility + //if (worker->mFormattedImage.notNull()) if (state == LLTextureFetchWorker::LOAD_FROM_SIMULATOR) { S32 data_size = FIRST_PACKET_SIZE + (worker->mLastPacket-1) * MAX_IMG_PACKET_SIZE; @@ -3756,6 +3784,7 @@ S32 LLTextureFetch::getFetchState(const LLUUID& id, F32& data_progress_p, F32& r data_progress = (F32)data_size / (F32)worker->mFileSize; } else if (worker->mFormattedImage.notNull()) + // { data_progress = (F32)worker->mFormattedImage->getDataSize() / (F32)worker->mFileSize; } diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h index bf6732963f..2552a6c43b 100644 --- a/indra/newview/lltexturefetch.h +++ b/indra/newview/lltexturefetch.h @@ -101,11 +101,13 @@ public: // Threads: T* bool updateRequestPriority(const LLUUID& id, F32 priority); + // OpenSim compatibility // Threads: T* bool receiveImageHeader(const LLHost& host, const LLUUID& id, U8 codec, U16 packets, U32 totalbytes, U16 data_size, U8* data); // Threads: T* bool receiveImagePacket(const LLHost& host, const LLUUID& id, U16 packet_num, U16 data_size, U8* data); + // // Threads: T* (but not safe) void setTextureBandwidth(F32 bandwidth) { mTextureBandwidth = bandwidth; } @@ -227,11 +229,13 @@ public: // ---------------------------------- protected: + // OpenSim compatibility // Threads: T* (but Ttf in practice) void addToNetworkQueue(LLTextureFetchWorker* worker); // Threads: T* void removeFromNetworkQueue(LLTextureFetchWorker* worker, bool cancel); + // // Threads: T* void addToHTTPQueue(const LLUUID& id); @@ -251,8 +255,10 @@ protected: bool runCondition(); private: + // OpenSim compatibility // Threads: Tmain void sendRequestListToSimulators(); + // // Threads: Ttf /*virtual*/ void startThread(void); @@ -319,7 +325,7 @@ public: private: LLMutex mQueueMutex; //to protect mRequestMap and mCommands only - LLMutex mNetworkQueueMutex; //to protect mNetworkQueue, mHTTPTextureQueue and mCancelQueue. + LLMutex mNetworkQueueMutex; //to protect mNetworkQueue, mHTTPTextureQueue and mCancelQueue. // OpenSim compatibility LLTextureCache* mTextureCache; LLImageDecodeThread* mImageDecodeThread; @@ -330,10 +336,10 @@ private: // Set of requests that require network data typedef std::set queue_t; - queue_t mNetworkQueue; // Mfnq + queue_t mNetworkQueue; // Mfnq // OpenSim compatibility queue_t mHTTPTextureQueue; // Mfnq typedef std::map > cancel_queue_t; - cancel_queue_t mCancelQueue; // Mfnq + cancel_queue_t mCancelQueue; // Mfnq // OpenSim compatibility F32 mTextureBandwidth; // F32 mMaxBandwidth; // Mfnq LLTextureInfo mTextureInfo; diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp index 9962fea4e9..556a0208fd 100644 --- a/indra/newview/lltextureview.cpp +++ b/indra/newview/lltextureview.cpp @@ -236,7 +236,7 @@ void LLTextureBar::draw() { "CCH", LLColor4::cyan }, // LOAD_FROM_TEXTURE_CACHE { "DSK", LLColor4::blue }, // CACHE_POST { "NET", LLColor4::green }, // LOAD_FROM_NETWORK - { "SIM", LLColor4::green }, // LOAD_FROM_SIMULATOR + { "SIM", LLColor4::green }, // LOAD_FROM_SIMULATOR // OpenSim compatibility { "HTW", LLColor4::green }, // WAIT_HTTP_RESOURCE // Unique state codes //{ "HTW", LLColor4::green }, // WAIT_HTTP_RESOURCE2 diff --git a/indra/newview/lltoolbarview.cpp b/indra/newview/lltoolbarview.cpp index 3c73ed7857..010b9d128a 100644 --- a/indra/newview/lltoolbarview.cpp +++ b/indra/newview/lltoolbarview.cpp @@ -44,6 +44,7 @@ #include "llagent.h" // HACK for destinations guide on startup #include "llfloaterreg.h" // HACK for destinations guide on startup #include "llviewercontrol.h" // HACK for destinations guide on startup +#include "llinventorymodel.h" // HACK to disable starter avatars button for NUX #include @@ -382,6 +383,22 @@ bool LLToolBarView::loadToolbars(bool force_default) } } } + + // SL-18581: Don't show the starter avatar toolbar button for NUX users + LLViewerInventoryCategory* my_outfits_cat = gInventory.getCategory(gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS)); + if (gAgent.isFirstLogin() + && my_outfits_cat != NULL + && my_outfits_cat->getDescendentCount() > 0) + { + for (S32 i = LLToolBarEnums::TOOLBAR_FIRST; i <= LLToolBarEnums::TOOLBAR_LAST; i++) + { + if (mToolbars[i]) + { + mToolbars[i]->removeCommand(LLCommandId("avatar")); + } + } + } + mToolbarsLoaded = true; return true; } diff --git a/indra/newview/llviewerassetupload.cpp b/indra/newview/llviewerassetupload.cpp index 10c968051b..be6b45033b 100644 --- a/indra/newview/llviewerassetupload.cpp +++ b/indra/newview/llviewerassetupload.cpp @@ -928,11 +928,6 @@ void LLViewerAssetUpload::AssetInventoryUploadCoproc(LLCoreHttpUtil::HttpCorouti { floater_snapshot->notify(LLSD().with("set-finished", LLSD().with("ok", success).with("msg", "inventory"))); } - LLFloater* floater_outfit_snapshot = LLFloaterReg::findInstance("outfit_snapshot"); - if (uploadInfo->getAssetType() == LLAssetType::AT_TEXTURE && floater_outfit_snapshot && floater_outfit_snapshot->isShown()) - { - floater_outfit_snapshot->notify(LLSD().with("set-finished", LLSD().with("ok", success).with("msg", "inventory"))); - } } //========================================================================= @@ -1011,11 +1006,5 @@ void LLViewerAssetUpload::HandleUploadError(LLCore::HttpStatus status, LLSD &res floater_snapshot->notify(LLSD().with("set-finished", LLSD().with("ok", false).with("msg", "inventory"))); } } - - LLFloater* floater_outfit_snapshot = LLFloaterReg::findInstance("outfit_snapshot"); - if (uploadInfo->getAssetType() == LLAssetType::AT_TEXTURE && floater_outfit_snapshot && floater_outfit_snapshot->isShown()) - { - floater_outfit_snapshot->notify(LLSD().with("set-finished", LLSD().with("ok", false).with("msg", "inventory"))); - } } diff --git a/indra/newview/llvieweraudio.cpp b/indra/newview/llvieweraudio.cpp index 960fff004c..eaae615117 100644 --- a/indra/newview/llvieweraudio.cpp +++ b/indra/newview/llvieweraudio.cpp @@ -618,7 +618,20 @@ void audio_update_listener() if (gAudiop) { // update listener position because agent has moved - LLVector3d lpos_global = gAgentCamera.getCameraPositionGlobal(); + static LLUICachedControl mEarLocation("MediaSoundsEarLocation", 0); + LLVector3d ear_position; + switch(mEarLocation) + { + case 0: + default: + ear_position = gAgentCamera.getCameraPositionGlobal(); + break; + + case 1: + ear_position = gAgent.getPositionGlobal(); + break; + } + LLVector3d lpos_global = ear_position; LLVector3 lpos_global_f; lpos_global_f.setVec(lpos_global); diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index 91f212850f..c64fdb05bf 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -750,7 +750,7 @@ bool toggle_agent_pause(const LLSD& newvalue) //LLNavigationBar::getInstance()->setVisible(value); //gSavedSettings.setBOOL("ShowMiniLocationPanel", !value); - + //gViewerWindow->reshapeStatusBarContainer(); //return true; // } diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index 355d387e26..5bfaac1bfc 100644 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -103,7 +103,7 @@ #include "llfloaterobjectweights.h" #include "llfloateropenobject.h" #include "llfloateroutfitphotopreview.h" -#include "llfloateroutfitsnapshot.h" +#include "llfloatersimpleoutfitsnapshot.h" #include "llfloaterpathfindingcharacters.h" #include "llfloaterpathfindingconsole.h" #include "llfloaterpathfindinglinksets.h" @@ -204,6 +204,7 @@ #include "fsfloaterradar.h" #include "fsfloatersearch.h" #include "fsfloaterstatistics.h" +#include "fsfloaterstreamtitle.h" #include "fsfloaterteleporthistory.h" #include "fsfloatervoicecontrols.h" #include "fsfloatervolumecontrols.h" @@ -225,6 +226,7 @@ // handle secondlife:///app/openfloater/{NAME} URLs +const std::string FLOATER_PROFILE("profile"); class LLFloaterOpenHandler : public LLCommandHandler { public: @@ -241,8 +243,20 @@ public: const std::string floater_name = LLURI::unescape(params[0].asString()); // Support passing arguments to opened floater like secondlife:///app/openfloater/{NAME}?tab=msg&subtab=xyz - // LLFloaterReg::showInstance(floater_name); - LLFloaterReg::showInstance(floater_name, query_map); + //LLSD key; + //if (floater_name == FLOATER_PROFILE) + //{ + // key["id"] = gAgentID; + //} + //LLFloaterReg::showInstance(floater_name, key); + if (floater_name == FLOATER_PROFILE) + { + LLSD key; + key["id"] = gAgentID; + LLFloaterReg::showInstance(floater_name, key); + return true; + } + LLFloaterReg::showInstance(floater_name, query_map); return true; } @@ -458,7 +472,7 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("scene_load_stats", "floater_scene_load_stats.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("stop_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("snapshot", "floater_snapshot.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); - LLFloaterReg::add("outfit_snapshot", "floater_outfit_snapshot.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + LLFloaterReg::add("simple_outfit_snapshot", "floater_simple_outfit_snapshot.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); // Search floater is deferred to login now so we can tell what grid we're in. //LLFloaterReg::add("search", "floater_search.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("profile", "floater_profile.xml",(LLFloaterBuildFunc)&LLFloaterReg::build); @@ -504,6 +518,8 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("fs_placedetails", "floater_fs_placedetails.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("fs_protectedfolders", "floater_fs_protectedfolders.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("fs_radar", "floater_fs_radar.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + LLFloaterReg::add("fs_streamtitle", "floater_fs_streamtitle.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + LLFloaterReg::add("fs_streamtitlehistory", "floater_fs_streamtitlehistory.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("fs_teleporthistory", "floater_fs_teleporthistory.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("fs_voice_controls", "floater_fs_voice_controls.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("fs_volume_controls", "floater_fs_volume_controls.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); diff --git a/indra/newview/llviewerjointattachment.cpp b/indra/newview/llviewerjointattachment.cpp index 6a142f0145..5c9065e209 100644 --- a/indra/newview/llviewerjointattachment.cpp +++ b/indra/newview/llviewerjointattachment.cpp @@ -49,7 +49,7 @@ extern LLPipeline gPipeline; // Moved to header file -//const F32 MAX_ATTACHMENT_DIST = 3.5f; // meters? +//const F32 MAX_ATTACHMENT_DIST = 3.5f; // meters //----------------------------------------------------------------------------- // LLViewerJointAttachment() diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index 0dd0e201bb..e1d811a8f4 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -3648,7 +3648,20 @@ void LLViewerMediaImpl::calculateInterest() LLVector3d global_delta = agent_global - obj_global ; mProximityDistance = global_delta.magVecSquared(); // use distance-squared because it's cheaper and sorts the same. - LLVector3d camera_delta = gAgentCamera.getCameraPositionGlobal() - obj_global; + static LLUICachedControl mEarLocation("MediaSoundsEarLocation", 0); + LLVector3d ear_position; + switch(mEarLocation) + { + case 0: + default: + ear_position = gAgentCamera.getCameraPositionGlobal(); + break; + + case 1: + ear_position = agent_global; + break; + } + LLVector3d camera_delta = ear_position - obj_global; mProximityCamera = camera_delta.magVec(); } } diff --git a/indra/newview/llviewermedia_streamingaudio.cpp b/indra/newview/llviewermedia_streamingaudio.cpp index ed3cd120e2..30b71f1635 100644 --- a/indra/newview/llviewermedia_streamingaudio.cpp +++ b/indra/newview/llviewermedia_streamingaudio.cpp @@ -82,6 +82,9 @@ void LLStreamingAudio_MediaPlugins::stop() } mURL.clear(); + + // Stream meta data display + updateMetadata(); } void LLStreamingAudio_MediaPlugins::pause(int pause) @@ -105,6 +108,9 @@ void LLStreamingAudio_MediaPlugins::update() { if (mMediaPlugin) mMediaPlugin->idle(); + + // Stream meta data display + updateMetadata(); } int LLStreamingAudio_MediaPlugins::isPlaying() @@ -164,22 +170,22 @@ LLPluginClassMedia* LLStreamingAudio_MediaPlugins::initializeMedia(const std::st } // stream metadata from plugin -bool LLStreamingAudio_MediaPlugins::getNewMetadata(LLSD& metadata) +void LLStreamingAudio_MediaPlugins::updateMetadata() noexcept { if (!mMediaPlugin) { - metadata.clear(); - return false; + return; } if (mTitle != mMediaPlugin->getTitle() || mArtist != mMediaPlugin->getArtist()) { mArtist = mMediaPlugin->getArtist(); mTitle = mMediaPlugin->getTitle(); - metadata["ARTIST"] = mArtist; - metadata["TITLE"] = mTitle; - return true; + mMetadata.clear(); + mMetadata["ARTIST"] = mArtist; + mMetadata["TITLE"] = mTitle; + + mMetadataUpdateSignal(mMetadata); } - return false; } // diff --git a/indra/newview/llviewermedia_streamingaudio.h b/indra/newview/llviewermedia_streamingaudio.h index 279183aad7..7d896d8eb8 100644 --- a/indra/newview/llviewermedia_streamingaudio.h +++ b/indra/newview/llviewermedia_streamingaudio.h @@ -51,7 +51,7 @@ class LLStreamingAudio_MediaPlugins : public LLStreamingAudioInterface /*virtual*/ std::string getURL(); // For FS metadata extraction - virtual bool getNewMetadata(LLSD& metadata); + LLSD getCurrentMetadata() const noexcept { return mMetadata; } // private: @@ -62,8 +62,11 @@ private: std::string mURL; // stream metadata from plugin + void updateMetadata() noexcept; + std::string mArtist; std::string mTitle; + LLSD mMetadata; // F32 mGain; diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 2f1b5d26f2..a6d4472a18 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -5479,6 +5479,10 @@ class LLLandSit : public view_listener_t return true; // [/RLVa:KB] + if (gAgent.isSitting()) + { + gAgent.standUp(); + } LLVector3d posGlobal = LLToolPie::getInstance()->getPick().mPosGlobal; LLQuaternion target_rot; diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp index 8ad095d6e4..ded7958cf5 100644 --- a/indra/newview/llviewermenufile.cpp +++ b/indra/newview/llviewermenufile.cpp @@ -38,7 +38,7 @@ #include "llfloatermap.h" #include "llfloatermodelpreview.h" #include "llfloatersnapshot.h" -#include "llfloateroutfitsnapshot.h" +#include "llfloatersimpleoutfitsnapshot.h" #include "llimage.h" #include "llimagebmp.h" #include "llimagepng.h" @@ -744,7 +744,7 @@ class LLFileEnableCloseAllWindows : public view_listener_t bool handleEvent(const LLSD& userdata) { LLFloaterSnapshot* floater_snapshot = LLFloaterSnapshot::findInstance(); - LLFloaterOutfitSnapshot* floater_outfit_snapshot = LLFloaterOutfitSnapshot::findInstance(); + LLFloaterSimpleOutfitSnapshot* floater_outfit_snapshot = LLFloaterSimpleOutfitSnapshot::findInstance(); bool is_floaters_snapshot_opened = (floater_snapshot && floater_snapshot->isInVisibleChain()) || (floater_outfit_snapshot && floater_outfit_snapshot->isInVisibleChain()); bool open_children = gFloaterView->allChildrenClosed() && !is_floaters_snapshot_opened; @@ -761,7 +761,7 @@ class LLFileCloseAllWindows : public view_listener_t LLFloaterSnapshot* floater_snapshot = LLFloaterSnapshot::findInstance(); if (floater_snapshot) floater_snapshot->closeFloater(app_quitting); - LLFloaterOutfitSnapshot* floater_outfit_snapshot = LLFloaterOutfitSnapshot::findInstance(); + LLFloaterSimpleOutfitSnapshot* floater_outfit_snapshot = LLFloaterSimpleOutfitSnapshot::findInstance(); if (floater_outfit_snapshot) floater_outfit_snapshot->closeFloater(app_quitting); if (gMenuHolder) gMenuHolder->hideMenus(); diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 8660fb2898..aa94093717 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -334,7 +334,8 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe mLastUpdateType(OUT_UNKNOWN), mLastUpdateCached(FALSE), mCachedMuteListUpdateTime(0), - mCachedOwnerInMuteList(false) + mCachedOwnerInMuteList(false), + mRiggedAttachedWarned(false) { if (!is_global) { diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index c5d181d2c9..7273008eb2 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -719,6 +719,8 @@ public: // Replace textures with web pages on this object while drawing BOOL mRenderMedia; + bool mRiggedAttachedWarned; + // In bits S32 mBestUpdatePrecision; @@ -932,8 +934,6 @@ public: LLViewerPartSourceScript* getPartSourceScript() { return mPartSourcep.get(); } bool getPhysicsShapeUnknown () { return mPhysicsShapeUnknown; } // - - bool mCheckRigOnHUD = true; // Warn the user when they wear a rigged item on a HUD attachment point }; /////////////////// diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp index d322951c15..12d889cadb 100644 --- a/indra/newview/llviewerparcelmgr.cpp +++ b/indra/newview/llviewerparcelmgr.cpp @@ -2061,7 +2061,7 @@ void LLViewerParcelMgr::optionallyStartMusic(const std::string &music_url, const // only play music when you enter a new parcel if the UI control for this // was not *explicitly* stopped by the user. (part of SL-4878) // Media/Stream separation - //LLPanelNearByMedia* nearby_media_panel = gStatusBar->getNearbyMediaPanel(); + //LLPanelNearByMedia* nearby_media_panel = gStatusBar ? gStatusBar->getNearbyMediaPanel() : NULL; LLViewerAudio* viewer_audio = LLViewerAudio::getInstance(); // ask mode //todo constants diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index f8fa4370e3..5572e6f9f3 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -45,11 +45,13 @@ #include "llxmltree.h" #include "message.h" +#include "lldrawpoolbump.h" // to init bumpmap images #include "lltexturecache.h" #include "lltexturefetch.h" #include "llviewercontrol.h" #include "llviewertexture.h" #include "llviewermedia.h" +#include "llviewernetwork.h" #include "llviewerregion.h" #include "llviewerstats.h" #include "pipeline.h" @@ -142,9 +144,6 @@ void LLViewerTextureList::doPreloadImages() //uv_test->setClamp(FALSE, FALSE); //uv_test->setMipFilterNearest(TRUE, TRUE); - // prefetch specific UUIDs - LLViewerTextureManager::getFetchedTexture(IMG_SHOT); - LLViewerTextureManager::getFetchedTexture(IMG_SMOKE_POOF); LLViewerFetchedTexture* image = LLViewerTextureManager::getFetchedTextureFromFile("silhouette.j2c", FTT_LOCAL_FILE, MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI); if (image) { @@ -163,12 +162,6 @@ void LLViewerTextureList::doPreloadImages() image->setAddressMode(LLTexUnit::TAM_WRAP); mImagePreloads.insert(image); } - image = LLViewerTextureManager::getFetchedTexture(DEFAULT_WATER_NORMAL, FTT_DEFAULT, MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI); - if (image) - { - image->setAddressMode(LLTexUnit::TAM_WRAP); - mImagePreloads.insert(image); - } image = LLViewerTextureManager::getFetchedTextureFromFile("transparent.j2c", FTT_LOCAL_FILE, MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI, LLViewerTexture::FETCHED_TEXTURE, 0, 0, IMG_TRANSPARENT); if (image) @@ -201,7 +194,21 @@ void LLViewerTextureList::doPreloadImages() static std::string get_texture_list_name() { - return gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "texture_list_" + gSavedSettings.getString("LoginLocation") + "." + gDirUtilp->getUserName() + ".xml"); + // OpenSim compatibility + //if (LLGridManager::getInstance()->isInProductionGrid()) + if (LLGridManager::getInstance()->isInSLMain()) + // + { + return gDirUtilp->getExpandedFilename(LL_PATH_CACHE, + "texture_list_" + gSavedSettings.getString("LoginLocation") + "." + gDirUtilp->getUserName() + ".xml"); + } + else + { + const std::string& grid_id_str = LLGridManager::getInstance()->getGridId(); + const std::string& grid_id_lower = utf8str_tolower(grid_id_str); + return gDirUtilp->getExpandedFilename(LL_PATH_CACHE, + "texture_list_" + gSavedSettings.getString("LoginLocation") + "." + gDirUtilp->getUserName() + "." + grid_id_lower + ".xml"); + } } void LLViewerTextureList::doPrefetchImages() @@ -210,6 +217,26 @@ void LLViewerTextureList::doPrefetchImages() gTextureTimer.start(); gTextureTimer.pause(); + // todo: do not load without getViewerAssetUrl() + // either fail login without caps or provide this + // in some other way, textures won't load otherwise + LLViewerFetchedTexture *imagep = findImage(DEFAULT_WATER_NORMAL, TEX_LIST_STANDARD); + if (!imagep) + { + // add it to mImagePreloads only once + imagep = LLViewerTextureManager::getFetchedTexture(DEFAULT_WATER_NORMAL, FTT_DEFAULT, MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI); + if (imagep) + { + imagep->setAddressMode(LLTexUnit::TAM_WRAP); + mImagePreloads.insert(imagep); + } + } + + LLViewerTextureManager::getFetchedTexture(IMG_SHOT); + LLViewerTextureManager::getFetchedTexture(IMG_SMOKE_POOF); + + LLStandardBumpmap::addstandard(); + if (LLAppViewer::instance()->getPurgeCache()) { // cache was purged, no point @@ -1761,6 +1788,7 @@ void LLViewerTextureList::updateTexMemDynamic() /////////////////////////////////////////////////////////////////////////////// +// OpenSim compatibility // static void LLViewerTextureList::receiveImageHeader(LLMessageSystem *msg, void **user_data) { @@ -1905,7 +1933,7 @@ void LLViewerTextureList::receiveImagePacket(LLMessageSystem *msg, void **user_d delete[] data; } } - +// // We've been that the asset server does not contain the requested image id. // static diff --git a/indra/newview/llviewertexturelist.h b/indra/newview/llviewertexturelist.h index 80d7dcbfab..66aec3e8ca 100644 --- a/indra/newview/llviewertexturelist.h +++ b/indra/newview/llviewertexturelist.h @@ -99,8 +99,10 @@ public: const S32 max_image_dimentions = LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT); static LLPointer convertToUploadFile(LLPointer raw_image, const S32 max_image_dimentions = LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT); static void processImageNotInDatabase( LLMessageSystem *msg, void **user_data ); + // OpenSim compatibility static void receiveImageHeader(LLMessageSystem *msg, void **user_data); static void receiveImagePacket(LLMessageSystem *msg, void **user_data); + // public: LLViewerTextureList(); @@ -138,7 +140,9 @@ public: static bool canUseDynamicTextureMemory(); // + // Local UI images void doPreloadImages(); + // Network images. Needs caps and cache to work void doPrefetchImages(); void clearFetchingRequests(); diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 520064b933..b8f91d2dff 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -2433,21 +2433,24 @@ void LLViewerWindow::initWorldUI() // Force gFloaterTools to initialize LLFloaterReg::getInstance("build"); - // Status bar LLPanel* status_bar_container = getRootView()->getChild("status_bar_container"); gStatusBar = new LLStatusBar(status_bar_container->getLocalRect()); + // Undo weird LL messing around with main view + //gStatusBar->setFollows(FOLLOWS_LEFT | FOLLOWS_TOP | FOLLOWS_RIGHT); gStatusBar->setFollowsAll(); gStatusBar->setShape(status_bar_container->getLocalRect()); // sync bg color with menu bar gStatusBar->setBackgroundColor( gMenuBarView->getBackgroundColor().get() ); // add InBack so that gStatusBar won't be drawn over menu - status_bar_container->addChildInBack(gStatusBar); - status_bar_container->setVisible(TRUE); + // Undo weird LL messing around with main view + //status_bar_container->addChildInBack(gStatusBar, 2/*tab order, after menu*/); + status_bar_container->addChildInBack(gStatusBar); + status_bar_container->setVisible(TRUE); // Make navigation bar part of the UI // // Navigation bar - // LLPanel* nav_bar_container = getRootView()->getChild("topinfo_bar_container"); + // LLView* nav_bar_container = getRootView()->getChild("nav_bar_container"); // LLNavigationBar* navbar = LLNavigationBar::getInstance(); // navbar->setShape(nav_bar_container->getLocalRect()); @@ -2459,6 +2462,10 @@ void LLViewerWindow::initWorldUI() // { // navbar->setVisible(FALSE); // } + // else + // { + // reshapeStatusBarContainer(); + //} // Force navigation bar to initialize LLNavigationBar::getInstance(); @@ -7155,6 +7162,27 @@ LLRect LLViewerWindow::getChatConsoleRect() return console_rect; } + +void LLViewerWindow::reshapeStatusBarContainer() +{ + LLPanel* status_bar_container = getRootView()->getChild("status_bar_container"); + LLView* nav_bar_container = getRootView()->getChild("nav_bar_container"); + + S32 new_height = status_bar_container->getRect().getHeight(); + S32 new_width = status_bar_container->getRect().getWidth(); + + if (gSavedSettings.getBOOL("ShowNavbarNavigationPanel")) + { + // Navigation bar is outside visible area, expand status_bar_container to show it + new_height += nav_bar_container->getRect().getHeight(); + } + else + { + // collapse status_bar_container + new_height -= nav_bar_container->getRect().getHeight(); + } + status_bar_container->reshape(new_width, new_height, TRUE); +} //---------------------------------------------------------------------------- diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h index 98b3433d00..91fe91add0 100644 --- a/indra/newview/llviewerwindow.h +++ b/indra/newview/llviewerwindow.h @@ -178,6 +178,8 @@ public: bool getUIVisibility(); void handlePieMenu(S32 x, S32 y, MASK mask); + void reshapeStatusBarContainer(); + BOOL handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK mask, EMouseClickType clicktype, BOOL down); // diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp index b83b09a8af..83bc0e6c6d 100644 --- a/indra/newview/llvlcomposition.cpp +++ b/indra/newview/llvlcomposition.cpp @@ -290,6 +290,12 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, BOOL delete_raw = (mDetailTextures[i]->reloadRawImage(ddiscard) != NULL) ; if(mDetailTextures[i]->getRawImageLevel() != ddiscard)//raw iamge is not ready, will enter here again later. { + if (mDetailTextures[i]->getDecodePriority() <= 0.0f && !mDetailTextures[i]->hasSavedRawImage()) + { + mDetailTextures[i]->setBoostLevel(LLGLTexture::BOOST_MAP); + mDetailTextures[i]->forceToRefetchTexture(ddiscard); + } + if(delete_raw) { mDetailTextures[i]->destroyRawImage() ; diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 3e795d846e..77331ded14 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -11816,7 +11816,7 @@ void LLVOAvatar::updateVisualComplexity() // with an avatar. This will be either an attached object or an animated // object. void LLVOAvatar::accountRenderComplexityForObject( - const LLViewerObject *attached_object, + LLViewerObject *attached_object, const F32 max_attachment_complexity, LLVOVolume::texture_cost_t& textures, U32& cost, @@ -11916,7 +11916,7 @@ void LLVOAvatar::accountRenderComplexityForObject( && attached_object->mDrawable) { textures.clear(); - + BOOL is_rigged_mesh = attached_object->isRiggedMesh(); mAttachmentSurfaceArea += attached_object->recursiveGetScaledSurfaceArea(); const LLVOVolume* volume = attached_object->mDrawable->getVOVolume(); @@ -11937,6 +11937,7 @@ void LLVOAvatar::accountRenderComplexityForObject( iter != child_list.end(); ++iter) { LLViewerObject* childp = *iter; + is_rigged_mesh |= childp->isRiggedMesh(); const LLVOVolume* chld_volume = dynamic_cast(childp); if (chld_volume) { @@ -11945,6 +11946,16 @@ void LLVOAvatar::accountRenderComplexityForObject( hud_object_complexity.objectsCount++; } } + if (is_rigged_mesh && !attached_object->mRiggedAttachedWarned) + { + LLSD args; + LLViewerInventoryItem* itemp = gInventory.getItem(attached_object->getAttachmentItemID()); + args["NAME"] = itemp ? itemp->getName() : LLTrans::getString("Unknown"); + args["POINT"] = LLTrans::getString(getTargetAttachmentPoint(attached_object)->getName()); + LLNotificationsUtil::add("RiggedMeshAttachedToHUD", args); + + attached_object->mRiggedAttachedWarned = true; + } hud_object_complexity.texturesCount += textures.size(); @@ -12073,64 +12084,12 @@ void LLVOAvatar::calculateUpdateRenderComplexity() attachment_iter != attachment->mAttachedObjects.end(); ++attachment_iter) { - const LLViewerObject* attached_object = attachment_iter->get(); + LLViewerObject* attached_object = attachment_iter->get(); accountRenderComplexityForObject(attached_object, max_attachment_complexity, // Show per-item complexity in COF //textures, cost, hud_complexity_list, object_complexity_list); textures, cost, hud_complexity_list, object_complexity_list, item_complexity, temp_item_complexity); // - - // FIRE-31330: Check if this attachment is on the HUD and contains rigged mesh. - // No need for isSelf() as HUD attachments always are owned by us. - // NOTE: This function should be revised once we have better information - // about pending/loaded rigging data and moved to a more appropriate - // place in the code. For now, this is a good spot as the complexity calculation - // gets updated when rigging data arrives, so we can reliably identify rigged - // attachments where the skinning information took a while to load. - if (attached_object->isHUDAttachment() && attached_object->mCheckRigOnHUD && !attached_object->isTempAttachment()) - { - // check if the root object is rigged - bool is_rigged = attached_object->isRiggedMesh(); - - // if not, check if any of its children is rigged - if (!is_rigged) - { - LLViewerObject::const_child_list_t& child_list = attached_object->getChildren(); - for (auto childp : child_list) - { - if (childp && childp->isRiggedMesh()) - { - is_rigged = true; - break; - } - } - } - - // if it is rigged, display the warning dialog once per object - if (is_rigged) - { - // can't use attached_object as it is const, so grab it from the iterator instead - attachment_iter->get()->mCheckRigOnHUD = false; - - LLSD args; - - LLViewerInventoryItem* inv_object = gInventory.getItem(attached_object->getAttachmentItemID()); - - if (inv_object) - { - args["NAME"] = inv_object->getName(); - } - else - { - args["NAME"] = LLTrans::getString("Unknown"); - } - - // can't use attached_object as it is const, so grab it from the iterator instead - args["HUD_POINT"] = LLTrans::getString(getTargetAttachmentPoint(attachment_iter->get())->getName()); - LLNotificationsUtil::add("AttachedRiggedObjectToHUD", args); - } - } - // } } diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 9856eea255..bb9278368c 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -304,7 +304,7 @@ public: // void idleUpdateRenderComplexity(); void idleUpdateDebugInfo(); - void accountRenderComplexityForObject(const LLViewerObject *attached_object, + void accountRenderComplexityForObject(LLViewerObject *attached_object, const F32 max_attachment_complexity, LLVOVolume::texture_cost_t& textures, U32& cost, diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index 939481dfdf..384c416c0f 100644 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -1363,8 +1363,8 @@ bool LLVivoxVoiceClient::establishVoiceConnection() if (result.has("connector")) { - LLVoiceVivoxStats::getInstance()->establishAttemptEnd(connected); connected = LLSD::Boolean(result["connector"]); + LLVoiceVivoxStats::getInstance()->establishAttemptEnd(connected); if (!connected) { if (result.has("retry") && ++retries <= CONNECT_RETRY_MAX && !sShuttingDown) @@ -4708,9 +4708,7 @@ void LLVivoxVoiceClient::messageEvent( IM_NOTHING_SPECIAL, // default arg 0, // default arg LLUUID::null, // default arg - LLVector3::zero, // default arg - true); // prepend name and make it a link to the user's profile - + LLVector3::zero); // default arg } } } diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp index 7f981943d1..752e57d346 100644 --- a/indra/newview/llworld.cpp +++ b/indra/newview/llworld.cpp @@ -186,7 +186,6 @@ void LLWorld::refreshLimits() mMinPrimYPos = 0.f; mMinPrimZPos = OS_MIN_OBJECT_Z; mMaxDragDistance = 10000.f; - mClassicCloudsEnabled = FALSE; mAllowParcelWindLight = TRUE; mEnableTeenMode = FALSE; //get saved settings? mEnforceMaxBuild = FALSE; @@ -226,7 +225,6 @@ void LLWorld::refreshLimits() mMinPrimYPos = 0.f; mMinPrimZPos = SL_MIN_OBJECT_Z; mMaxDragDistance = 10000.f; - mClassicCloudsEnabled = FALSE; mAllowParcelWindLight = FALSE; mEnableTeenMode = FALSE; //get saved settings? mEnforceMaxBuild = FALSE; @@ -413,7 +411,6 @@ void LLWorld::setTerrainDetailScale(F32 val) void LLWorld::setAllowMinimap(BOOL val) { mAllowMinimap = val; } void LLWorld::setAllowPhysicalPrims(BOOL val) { mAllowPhysicalPrims = val; } void LLWorld::setAllowRenderWater(BOOL val) { mAllowRenderWater = val; } -void LLWorld::setSkyUseClassicClouds(BOOL val) { mClassicCloudsEnabled = val; } void LLWorld::setAllowParcelWindLight(BOOL val) { mAllowParcelWindLight = val; } void LLWorld::setEnableTeenMode(BOOL val) { mEnableTeenMode = val; } void LLWorld::setEnforceMaxBuild(BOOL val) { mEnforceMaxBuild = val; } diff --git a/indra/newview/llworld.h b/indra/newview/llworld.h index 066adc273c..743f792dec 100644 --- a/indra/newview/llworld.h +++ b/indra/newview/llworld.h @@ -147,7 +147,6 @@ public: F32 getMinPrimZPos() const { return mMinPrimZPos; } F32 getMaxDragDistance() const { return mMaxDragDistance; } F32 getMaxPhysPrimScale() const { return mMaxPhysPrimScale; } - BOOL getSkyUseClassicClouds() const { return mClassicCloudsEnabled; } BOOL getAllowParcelWindLight() const{ return mAllowParcelWindLight; } BOOL getEnableTeenMode() const { return mEnableTeenMode; } BOOL getEnforceMaxBuild() const { return mEnforceMaxBuild; } @@ -180,7 +179,6 @@ public: void setMinPrimZPos(F32 val); void setMaxDragDistance(F32 val); void setMaxPhysPrimScale(F32 val); - void setSkyUseClassicClouds(BOOL val); void setAllowParcelWindLight(BOOL val); void setEnableTeenMode(BOOL val); void setEnforceMaxBuild(BOOL val); @@ -311,8 +309,6 @@ private: U32 mNumOfActiveCachedObjects; U64MicrosecondsImplicit mSpaceTimeUSec; - BOOL mClassicCloudsEnabled; - //////////////////////////// // // Data for "Fake" objects diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 7a314a74c8..8a5c7c95da 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -1930,15 +1930,20 @@ void LLPipeline::unlinkDrawable(LLDrawable *drawable) void LLPipeline::removeMutedAVsLights(LLVOAvatar* muted_avatar) { LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; - for (light_set_t::iterator iter = gPipeline.mNearbyLights.begin(); - iter != gPipeline.mNearbyLights.end(); iter++) - { - if (iter->drawable->getVObj()->isAttachment() && iter->drawable->getVObj()->getAvatar() == muted_avatar) - { - gPipeline.mLights.erase(iter->drawable); - gPipeline.mNearbyLights.erase(iter); - } - } + light_set_t::iterator iter = gPipeline.mNearbyLights.begin(); + + while (iter != gPipeline.mNearbyLights.end()) + { + if (iter->drawable->getVObj()->isAttachment() && iter->drawable->getVObj()->getAvatar() == muted_avatar) + { + gPipeline.mLights.erase(iter->drawable); + iter = gPipeline.mNearbyLights.erase(iter); + } + else + { + iter++; + } + } } U32 LLPipeline::addObject(LLViewerObject *vobj) @@ -7504,7 +7509,7 @@ void LLPipeline::doResetVertexBuffers(bool forced) LLPathingLib::getInstance()->cleanupVBOManager(); } LLVOPartGroup::destroyGL(); - gGL.resetVertexBuffer(); + gGL.resetVertexBuffer(); SUBSYSTEM_CLEANUP(LLVertexBuffer); @@ -11264,6 +11269,8 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar) if (preview_avatar) { // Only show rigged attachments for preview + // For the sake of performance and so that static + // objects won't obstruct previewing changes LLVOAvatar::attachment_map_t::iterator iter; for (iter = avatar->mAttachmentPoints.begin(); iter != avatar->mAttachmentPoints.end(); @@ -11276,12 +11283,33 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar) { LLViewerObject* attached_object = attachment_iter->get(); // FIRE-31966: Some mesh bodies/objects don't show in shape editor previews -> show everything but animesh - //if (attached_object && attached_object->isRiggedMesh()) + //if (attached_object) + //{ + // if (attached_object->isRiggedMesh()) + // { + // markVisible(attached_object->mDrawable->getSpatialBridge(), *viewer_camera); + // } + // else + // { + // // sometimes object is a linkset and rigged mesh is a child + // LLViewerObject::const_child_list_t& child_list = attached_object->getChildren(); + // for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); + // iter != child_list.end(); iter++) + // { + // LLViewerObject* child = *iter; + // if (child->isRiggedMesh()) + // { + // markVisible(attached_object->mDrawable->getSpatialBridge(), *viewer_camera); + // break; + // } + // } + // } + //} if (attached_object && !attached_object->getControlAvatar()) - // { markVisible(attached_object->mDrawable->getSpatialBridge(), *viewer_camera); } + // } } } diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index 7fd13f8260..fd7128e7aa 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -475,7 +475,7 @@ public: RENDER_TYPE_PASS_SIMPLE_RIGGED = LLRenderPass::PASS_SIMPLE_RIGGED, RENDER_TYPE_PASS_GRASS = LLRenderPass::PASS_GRASS, RENDER_TYPE_PASS_FULLBRIGHT = LLRenderPass::PASS_FULLBRIGHT, - RENDER_TYPE_PASS_FULLBRIGHT_RIGGED = LLRenderPass::PASS_FULLBRIGHT_RIGGED, // Fix apparent copy&paste issue + RENDER_TYPE_PASS_FULLBRIGHT_RIGGED = LLRenderPass::PASS_FULLBRIGHT_RIGGED, RENDER_TYPE_PASS_INVISIBLE = LLRenderPass::PASS_INVISIBLE, RENDER_TYPE_PASS_INVISIBLE_RIGGED = LLRenderPass::PASS_INVISIBLE_RIGGED, RENDER_TYPE_PASS_INVISI_SHINY = LLRenderPass::PASS_INVISI_SHINY, diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml index 972ad9e8f6..9049f45373 100644 --- a/indra/newview/skins/default/colors.xml +++ b/indra/newview/skins/default/colors.xml @@ -1274,6 +1274,12 @@ + + diff --git a/indra/newview/skins/default/xui/de/floater_about_land.xml b/indra/newview/skins/default/xui/de/floater_about_land.xml index b2792e7476..bf85aaf3e3 100644 --- a/indra/newview/skins/default/xui/de/floater_about_land.xml +++ b/indra/newview/skins/default/xui/de/floater_about_land.xml @@ -466,7 +466,7 @@ Nur große Parzellen können in der Suche aufgeführt werden. Medien: - + diff --git a/indra/newview/skins/default/xui/de/floater_fs_nearby_chat.xml b/indra/newview/skins/default/xui/de/floater_fs_nearby_chat.xml index 989d0c76ce..d9fca4a1b7 100644 --- a/indra/newview/skins/default/xui/de/floater_fs_nearby_chat.xml +++ b/indra/newview/skins/default/xui/de/floater_fs_nearby_chat.xml @@ -4,9 +4,6 @@ An Chat in der Nähe - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + Capture a 360° equirectangular image The physics shape contains bad confirmation data. Try to correct the physics model. + + + Missing data. Make sure high lod is present and valid. Set the physics model if not set. + The physics shape does not have correct version. Set the correct version for the physics model. diff --git a/indra/newview/skins/default/xui/es/floater_fs_nearby_chat.xml b/indra/newview/skins/default/xui/es/floater_fs_nearby_chat.xml index f52862edd7..5fbcae9803 100644 --- a/indra/newview/skins/default/xui/es/floater_fs_nearby_chat.xml +++ b/indra/newview/skins/default/xui/es/floater_fs_nearby_chat.xml @@ -4,9 +4,6 @@ Decir en el chat local - -