Merge branch 'master' of https://vcs.firestormviewer.org/phoenix-firestorm
# Conflicts: # indra/newview/viewer_manifest.pymaster
commit
68c04f41ad
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -672,9 +672,9 @@
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>ae90d19cdcddf539f6d0b41cab12f918</string>
|
||||
<string>7b4aceaed511d44c4d1354b2162b59c7</string>
|
||||
<key>url</key>
|
||||
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/72773/702861/bugsplat-1.0.7.552580-darwin64-552580.tar.bz2</string>
|
||||
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/107398/936936/bugsplat-1.0.7.576560-darwin64-576560.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>darwin64</string>
|
||||
|
|
@ -684,9 +684,9 @@
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>f5936eceb6a33ff0f1cc31996a40f29c</string>
|
||||
<string>53918c7c74b943cdc0bb90caf9657a84</string>
|
||||
<key>url</key>
|
||||
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/72774/702905/bugsplat-3.6.0.8.552580-windows-552580.tar.bz2</string>
|
||||
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/107400/936949/bugsplat-4.0.3.0.576560-windows-576560.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows</string>
|
||||
|
|
@ -696,16 +696,16 @@
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>9cd940754e53e0670030b3da5ba8f373</string>
|
||||
<string>19d6a55db101f02e7eb531daf3e8cfd1</string>
|
||||
<key>url</key>
|
||||
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/72775/702906/bugsplat-3.6.0.8.552580-windows64-552580.tar.bz2</string>
|
||||
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/107401/936948/bugsplat-.576560-windows64-576560.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows64</string>
|
||||
</map>
|
||||
</map>
|
||||
<key>version</key>
|
||||
<string>3.6.0.8.552580</string>
|
||||
<string>4.0.3.0.576560</string>
|
||||
</map>
|
||||
<key>colladadom</key>
|
||||
<map>
|
||||
|
|
@ -3216,9 +3216,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>1dda5fb3bb649b0ab5a93f22df7cb11e</string>
|
||||
<string>2e8d817e7837dd6f4284b13fa3f5c15e</string>
|
||||
<key>url</key>
|
||||
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/96998/862110/viewer_manager-3.0.569958-darwin64-569958.tar.bz2</string>
|
||||
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/104765/917714/viewer_manager-3.0.575083-darwin64-575083.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>darwin64</string>
|
||||
|
|
@ -3240,9 +3240,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>30d1386d0a6883d898fc56757a789b8b</string>
|
||||
<string>3efa80faaf537e39a77218cd6efa9409</string>
|
||||
<key>url</key>
|
||||
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/97002/862130/viewer_manager-3.0.569958-windows-569958.tar.bz2</string>
|
||||
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/104766/917721/viewer_manager-3.0.575083-windows-575083.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows</string>
|
||||
|
|
@ -3253,7 +3253,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<key>source_type</key>
|
||||
<string>hg</string>
|
||||
<key>version</key>
|
||||
<string>3.0.569958</string>
|
||||
<string>3.0.575083</string>
|
||||
</map>
|
||||
<key>vlc-bin</key>
|
||||
<map>
|
||||
|
|
|
|||
|
|
@ -285,6 +285,7 @@ Beq Janus
|
|||
SL-15709
|
||||
SL-16021
|
||||
SL-16027
|
||||
SL-18637
|
||||
Beth Walcher
|
||||
Bezilon Kasei
|
||||
Biancaluce Robbiani
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
#define LL_STREAMINGAUDIO_H
|
||||
|
||||
#include "stdtypes.h" // from llcommon
|
||||
#include <boost/signals2.hpp>
|
||||
|
||||
// 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<void(const LLSD& metadata)>;
|
||||
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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
// <DKO> Stream metadata - originally by Shyotl Khur
|
||||
mMetadata.clear();
|
||||
mNewMetadata = true;
|
||||
// </DKO>
|
||||
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;
|
||||
|
||||
// <FS:Ansariel> Stream meta data display
|
||||
mMetadata.clear();
|
||||
mMetadataUpdateSignal(mMetadata);
|
||||
// </FS:Ansariel>
|
||||
}
|
||||
|
||||
if (mCurrentInternetStreamp)
|
||||
|
|
@ -411,29 +417,6 @@ void LLStreamingAudio_FMODSTUDIO::setGain(F32 vol)
|
|||
}
|
||||
}
|
||||
|
||||
// <DKO> 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;
|
||||
}
|
||||
// </DKO>
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
// manager of possibly-multiple internet audio streams
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
// <DKO> Streamtitle display
|
||||
bool mNewMetadata;
|
||||
LLSD mMetadata;
|
||||
// </DKO> Streamtitle display
|
||||
|
||||
bool mWasAlreadyPlaying;
|
||||
};
|
||||
|
||||
|
||||
#endif // LL_STREAMINGAUDIO_FMODSTUDIO_H
|
||||
|
|
|
|||
|
|
@ -95,7 +95,6 @@ set(llcommon_SOURCE_FILES
|
|||
llsys.cpp
|
||||
lltempredirect.cpp
|
||||
llthread.cpp
|
||||
llthreadlocalstorage.cpp
|
||||
llthreadsafequeue.cpp
|
||||
lltimer.cpp
|
||||
lltrace.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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -30,100 +30,6 @@
|
|||
|
||||
#include "llinstancetracker.h"
|
||||
|
||||
class LLThreadLocalPointerBase : public LLInstanceTracker<LLThreadLocalPointerBase>
|
||||
{
|
||||
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 <typename T>
|
||||
class LLThreadLocalPointer : public LLThreadLocalPointerBase
|
||||
{
|
||||
public:
|
||||
|
||||
LLThreadLocalPointer()
|
||||
{}
|
||||
|
||||
explicit LLThreadLocalPointer(T* value)
|
||||
{
|
||||
set(value);
|
||||
}
|
||||
|
||||
|
||||
LLThreadLocalPointer(const LLThreadLocalPointer<T>& 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<T>& 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<typename DERIVED_TYPE>
|
||||
class LLThreadLocalSingletonPointer
|
||||
{
|
||||
|
|
@ -139,10 +45,10 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
static LL_THREAD_LOCAL DERIVED_TYPE* sInstance;
|
||||
static thread_local DERIVED_TYPE* sInstance;
|
||||
};
|
||||
|
||||
template<typename DERIVED_TYPE>
|
||||
LL_THREAD_LOCAL DERIVED_TYPE* LLThreadLocalSingletonPointer<DERIVED_TYPE>::sInstance = NULL;
|
||||
thread_local DERIVED_TYPE* LLThreadLocalSingletonPointer<DERIVED_TYPE>::sInstance = NULL;
|
||||
|
||||
#endif // LL_LLTHREADLOCALSTORAGE_H
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<TimeBlockAccumulator>& timer_accumulator_buffer = mStackTimers;
|
||||
// update stacktimer parent pointers
|
||||
for (S32 i = 0, end_i = mStackTimers.size(); i < end_i; i++)
|
||||
|
|
|
|||
|
|
@ -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<PeriodicRecording> sRecording(new PeriodicRecording(200, PeriodicRecording::STARTED));
|
||||
return *sRecording;
|
||||
static thread_local PeriodicRecording sRecording(200, PeriodicRecording::STARTED);
|
||||
return sRecording;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -308,13 +308,13 @@ ThreadRecorder* get_master_thread_recorder()
|
|||
return sMasterThreadRecorder;
|
||||
}
|
||||
|
||||
LLThreadLocalPointer<ThreadRecorder>& get_thread_recorder_ptr()
|
||||
ThreadRecorder*& get_thread_recorder_ptr()
|
||||
{
|
||||
static LLThreadLocalPointer<ThreadRecorder> s_thread_recorder;
|
||||
static thread_local ThreadRecorder* s_thread_recorder;
|
||||
return s_thread_recorder;
|
||||
}
|
||||
|
||||
const LLThreadLocalPointer<ThreadRecorder>& get_thread_recorder()
|
||||
ThreadRecorder* get_thread_recorder()
|
||||
{
|
||||
return get_thread_recorder_ptr();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,7 +32,6 @@
|
|||
|
||||
#include "llmutex.h"
|
||||
#include "lltraceaccumulators.h"
|
||||
#include "llthreadlocalstorage.h"
|
||||
|
||||
namespace LLTrace
|
||||
{
|
||||
|
|
@ -92,7 +91,7 @@ namespace LLTrace
|
|||
|
||||
};
|
||||
|
||||
const LLThreadLocalPointer<ThreadRecorder>& get_thread_recorder();
|
||||
ThreadRecorder* get_thread_recorder();
|
||||
void set_thread_recorder(ThreadRecorder*);
|
||||
|
||||
void set_master_thread_recorder(ThreadRecorder*);
|
||||
|
|
|
|||
|
|
@ -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]);
|
||||
|
|
|
|||
|
|
@ -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"); // <FS:Ansariel> 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"); // <FS:Ansariel> 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"); // <FS:Ansariel> 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");
|
||||
|
|
|
|||
|
|
@ -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; // <FS:Ansariel> 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; // <FS:Ansariel> 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; // <FS:Ansariel> OpenSim compatibility
|
||||
extern char const* const _PREHASH_SimulatorViewerTimeMessage;
|
||||
extern char const* const _PREHASH_Rotation;
|
||||
extern char const* const _PREHASH_Selection;
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -62,6 +62,8 @@ public:
|
|||
mutable std::vector<S32> mJointNums;
|
||||
typedef std::vector<LLMatrix4a, boost::alignment::aligned_allocator<LLMatrix4a, 16>> matrix_list_t;
|
||||
matrix_list_t mInvBindMatrix;
|
||||
|
||||
// bones/joints position overrides
|
||||
matrix_list_t mAlternateBindMatrix;
|
||||
|
||||
LL_ALIGN_16(LLMatrix4a mBindShapeMatrix);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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<S32> 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);
|
||||
|
|
|
|||
|
|
@ -173,7 +173,7 @@ public:
|
|||
virtual BOOL removeItem() = 0;
|
||||
virtual void removeBatch(std::vector<LLFolderViewModelItem*>& 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; };
|
||||
|
|
|
|||
|
|
@ -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<LLScrollListItem*> data = getAllData();
|
||||
std::vector<LLScrollListItem*>::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;
|
||||
}
|
||||
|
||||
// <FS:Ansariel> Fix for FS-specific people list (radar)
|
||||
void LLScrollListCtrl::setFilterString(const std::string& str)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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<LLRect> 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<LLRect>::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<LLRect> LLTextBase::getSelctionRects()
|
||||
{
|
||||
// Nor supposed to be called without selection
|
||||
llassert(hasSelection());
|
||||
llassert(!mLineInfoList.empty());
|
||||
|
||||
std::vector<LLRect> 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<LLRect> 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<LLRect>::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;
|
||||
|
||||
|
|
|
|||
|
|
@ -685,6 +685,8 @@ protected:
|
|||
return mLabel.getString() + getToolTip();
|
||||
}
|
||||
|
||||
std::vector<LLRect> getSelctionRects();
|
||||
|
||||
protected:
|
||||
// text segmentation and flow
|
||||
segment_set_t mSegments;
|
||||
|
|
|
|||
|
|
@ -353,6 +353,7 @@ struct LLWindowWin32::LLWindowWin32Thread : public LL::ThreadPool
|
|||
{
|
||||
try
|
||||
{
|
||||
LL_DEBUGS("Window") << "post( callable ) to work queue" << LL_ENDL; // <FS:Beq/> extra debug for threaded window handler
|
||||
getQueue().post(std::forward<CALLABLE>(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();
|
||||
}
|
||||
|
||||
// <FS:Beq> 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;
|
||||
// </FS:Beq>
|
||||
|
||||
#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.");// <FS:Beq/> extra debug for threaded window handler
|
||||
}
|
||||
|
||||
void LLWindowWin32::post(const std::function<void()>& func)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -6951,11 +6951,11 @@
|
|||
<key>Type</key>
|
||||
<string>String</string>
|
||||
<key>Value</key>
|
||||
<string>https://search.[GRID]/?query_term=[QUERY]&search_type=[TYPE][COLLECTION]&maturity=[MATURITY]&lang=[LANGUAGE]&sid=[SESSION_ID]</string>
|
||||
<string>https://search.[GRID]/viewer/?query_term=[QUERY]&search_type=[TYPE][COLLECTION]&maturity=[MATURITY]&lang=[LANGUAGE]&sid=[SESSION_ID]</string>
|
||||
<key>Backup</key>
|
||||
<integer>0</integer>
|
||||
<!-- LL, possibly privacy leaking search string
|
||||
<string>https://search.[GRID]/?query_term=[QUERY]&search_type=[TYPE][COLLECTION]&maturity=[MATURITY]&lang=[LANGUAGE]&g=[GODLIKE]&sid=[SESSION_ID]&rid=[REGION_ID]&pid=[PARCEL_ID]&channel=[CHANNEL]&version=[VERSION]&major=[VERSION_MAJOR]&minor=[VERSION_MINOR]&patch=[VERSION_PATCH]&build=[VERSION_BUILD]</string>
|
||||
<string>https://search.[GRID]/viewer/?query_term=[QUERY]&search_type=[TYPE][COLLECTION]&maturity=[MATURITY]&lang=[LANGUAGE]&g=[GODLIKE]&sid=[SESSION_ID]&rid=[REGION_ID]&pid=[PARCEL_ID]&channel=[CHANNEL]&version=[VERSION]&major=[VERSION_MAJOR]&minor=[VERSION_MINOR]&patch=[VERSION_PATCH]&build=[VERSION_BUILD]</string>
|
||||
-->
|
||||
</map>
|
||||
<key>GuidebookURL</key>
|
||||
|
|
@ -18336,6 +18336,17 @@ Change of this parameter will affect the layout of buttons in notification toast
|
|||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>MediaSoundsEarLocation</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Location of the virtual ear for media and sounds</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>VoiceHost</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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); // <FS:Zi> 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;
|
||||
|
|
|
|||
|
|
@ -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:HG> FS-1734 seperate name and text styles for moderator
|
||||
//if (!is_history && bold_mods_chat && pIMSession && pIMSession->mSpeakers)
|
||||
|
|
|
|||
|
|
@ -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<LLButton>("chat_history_btn")->setCommitCallback(boost::bind(&FSFloaterNearbyChat::onHistoryButtonClicked, this));
|
||||
|
||||
getChild<LLButton>("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 )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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();}
|
||||
|
|
|
|||
|
|
@ -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<FSScrollListCtrl>("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<F32> 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<LLTextBox>("streamtitle");
|
||||
mHistoryBtn = findChild<LLButton>("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<FSFloaterStreamTitleHistory>("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<std::string>(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;
|
||||
}
|
||||
|
|
@ -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<FSStreamTitleManager>
|
||||
{
|
||||
LLSINGLETON_EMPTY_CTOR(FSStreamTitleManager);
|
||||
|
||||
public:
|
||||
~FSStreamTitleManager();
|
||||
|
||||
using history_vec_t = std::vector<std::string>;
|
||||
|
||||
using streamtitle_update_callback_t = boost::signals2::signal<void(std::string_view streamtitle)>;
|
||||
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<void(const history_vec_t& streamtitle_history)>;
|
||||
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<LLView> 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<LLFloater> mHistory{};
|
||||
|
||||
boost::signals2::connection mUpdateConnection{};
|
||||
|
||||
std::string mCurrentTitle{};
|
||||
std::string mCurrentDrawnTitle{};
|
||||
bool mResetTitle{ false };
|
||||
|
||||
};
|
||||
|
||||
#endif // FS_FLOATERSTREAMTITLE_H
|
||||
|
|
@ -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<FSWearableFavoritesItemsList> 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<LLUUID> 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<LLInventoryCallback>(NULL));
|
||||
link_inventory_object(sFolderID, item_id, LLPointer<LLInventoryCallback>(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<LLInventoryCallback>(NULL));
|
||||
remove_inventory_item(id, LLPointer<LLInventoryCallback>(nullptr));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -378,4 +371,3 @@ void FSFloaterWearableFavorites::onDoubleClick()
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
|
||||
#include "llfloater.h"
|
||||
#include "llwearableitemslist.h"
|
||||
#include <optional>
|
||||
|
||||
class LLButton;
|
||||
class LLFilterEditor;
|
||||
|
|
@ -92,6 +93,8 @@ private:
|
|||
void onOptionsMenuItemClicked(const LLSD& userdata);
|
||||
bool onOptionsMenuItemChecked(const LLSD& userdata);
|
||||
|
||||
static std::optional<LLUUID> getWearableFavoritesFolderID();
|
||||
|
||||
bool mInitialized;
|
||||
|
||||
boost::signals2::connection mDADCallbackConnection;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
// <FS:Ansariel> FIRE-21323: Crashfix
|
||||
//url = getRegion()->getCapability(capName);
|
||||
url = getRegion() ? getRegion()->getCapability(capName) : "";
|
||||
// </FS:Ansariel>
|
||||
if (!getRegion())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
std::string url = getRegion()->getCapability(capName);
|
||||
|
||||
if (url.empty())
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
||||
// <FS:Beq> [FIRE-32453] [BUG-232971] disconnect sooner to force the cache write.
|
||||
persistCachesAndSettings();
|
||||
// </FS:Beq>
|
||||
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()
|
||||
{
|
||||
// <FS:Beq> [FIRE-32453] [BUG-232971] disconnect sooner to force the cache write.
|
||||
persistCachesAndSettings();
|
||||
// </FS:Beq>
|
||||
LLApp::setQuitting();
|
||||
}
|
||||
|
||||
|
|
@ -6329,7 +6332,12 @@ void LLAppViewer::idleNetwork()
|
|||
}
|
||||
}
|
||||
add(LLStatViewer::NUM_NEW_OBJECTS, gObjectList.mNumNewObjects);
|
||||
|
||||
// <FS:Beq> [FIRE-32453] [BUG-232971] disconnect sooner to force the cache write.
|
||||
if(gDisconnected)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// </FS:Beq>
|
||||
// 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()); // <FS:Ansariel> 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();
|
||||
}
|
||||
// <FS:Beq> [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()); // <FS:Ansariel> 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()); // <FS:Ansariel> Contact sets
|
||||
// saveNameCache();
|
||||
// if (LLExperienceCache::instanceExists())
|
||||
// {
|
||||
// // TODO: LLExperienceCache::cleanup() logic should be moved to
|
||||
// // cleanupSingleton().
|
||||
// LLExperienceCache::instance().cleanup();
|
||||
// }
|
||||
|
||||
// </FS:Beq>
|
||||
// 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.
|
||||
|
|
|
|||
|
|
@ -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?
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ LLVector3d LLAudioSourceVO::getPosGlobal() const
|
|||
|
||||
bool LLAudioSourceVO::isInCutOffRadius(const LLVector3d pos_global, const F32 cutoff) const
|
||||
{
|
||||
static LLCachedControl<S32> ear_mode(gSavedSettings, "VoiceEarLocation", 0);
|
||||
static LLCachedControl<S32> 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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
// <FS:Beq> First run at profile behaviour fix for OpenSim
|
||||
#ifdef OPENSIM // maintain legacy behaviour for now
|
||||
// <FS:Beq> 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
|
||||
// </FS:Beq>
|
||||
// </FS:Beq>
|
||||
// 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)
|
||||
{
|
||||
// <FS:Beq> maintian legacy behaviour for OpenSim
|
||||
if(!gAgent.getRegionCapability("AgentProfile").empty())
|
||||
{
|
||||
// </FS:Beq>
|
||||
sendRequest(avatar_id, APT_PROPERTIES, "AvatarPropertiesRequest");
|
||||
}
|
||||
// <FS:Beq> 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");
|
||||
}
|
||||
// </FS:Beq>
|
||||
|
||||
void LLAvatarPropertiesProcessor::sendAvatarPicksRequest(const LLUUID& avatar_id)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ public:
|
|||
virtual BOOL removeItem() { return FALSE; }
|
||||
virtual void removeBatch(std::vector<LLFolderViewModelItem*>& 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; }
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -118,7 +118,6 @@ public:
|
|||
static void clear();
|
||||
static void addstandard();
|
||||
|
||||
static void init();
|
||||
static void shutdown();
|
||||
static void restoreGL();
|
||||
static void destroyGL();
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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<UpdateInfo> ptr_t;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -317,7 +317,6 @@ void LLFloaterIMNearbyChat::onOpen(const LLSD& key)
|
|||
restoreFloater();
|
||||
onCollapseToLine(this);
|
||||
}
|
||||
showTranslationCheckbox(LLTranslate::isTranslationConfigured());
|
||||
}
|
||||
|
||||
// virtual
|
||||
|
|
|
|||
|
|
@ -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"))
|
||||
|
|
|
|||
|
|
@ -255,7 +255,6 @@ BOOL LLFloaterIMSessionTab::postBuild()
|
|||
mGearBtn = getChild<LLButton>("gear_btn");
|
||||
mAddBtn = getChild<LLButton>("add_btn");
|
||||
mVoiceButton = getChild<LLButton>("voice_call_btn");
|
||||
mTranslationCheckBox = getChild<LLUICtrl>("translate_chat_checkbox_lp");
|
||||
|
||||
mParticipantListPanel = getChild<LLLayoutPanel>("speakers_list_panel");
|
||||
mRightPartPanel = getChild<LLLayoutPanel>("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*/)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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" // <FS:Ansariel> 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<LLOutfitSnapshotFloaterView> r("snapshot_outfit_floater_view");
|
||||
|
||||
///----------------------------------------------------------------------------
|
||||
/// Class LLFloaterOutfitSnapshot::Impl
|
||||
///----------------------------------------------------------------------------
|
||||
|
||||
// virtual
|
||||
LLPanelSnapshot* LLFloaterOutfitSnapshot::Impl::getActivePanel(LLFloaterSnapshotBase* floater, bool ok_if_not_found)
|
||||
{
|
||||
LLPanel* panel = floater->getChild<LLPanel>("panel_outfit_snapshot_inventory");
|
||||
LLPanelSnapshot* active_panel = dynamic_cast<LLPanelSnapshot*>(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<LLTextBox>("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<LLUICtrl>("file_size_label")->setTextArg("[SIZE]", got_snap ? bytes_string : floater->getString("unknown"));
|
||||
floater->getChild<LLUICtrl>("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<LLUICtrl>(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<LLPanel>("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<LLUICtrl>("new_snapshot_btn");
|
||||
childSetAction("new_snapshot_btn", ImplBase::onClickNewSnapshot, this);
|
||||
mRefreshLabel = getChild<LLUICtrl>("refresh_lbl");
|
||||
mSucceessLblPanel = getChild<LLUICtrl>("succeeded_panel");
|
||||
mFailureLblPanel = getChild<LLUICtrl>("failed_panel");
|
||||
|
||||
childSetCommitCallback("ui_check", ImplBase::onClickUICheck, this);
|
||||
getChild<LLUICtrl>("ui_check")->setValue(gSavedSettings.getBOOL("RenderUIInSnapshot"));
|
||||
|
||||
childSetCommitCallback("hud_check", ImplBase::onClickHUDCheck, this);
|
||||
getChild<LLUICtrl>("hud_check")->setValue(gSavedSettings.getBOOL("RenderHUDInSnapshot"));
|
||||
|
||||
// <FS:Ansariel> FIRE-15853: HUDs, interface or L$ balance checkbox don't update actual screenshot image
|
||||
childSetCommitCallback("currency_check", ImplBase::onClickCurrencyCheck, this);
|
||||
|
||||
getChild<LLUICtrl>("freeze_frame_check")->setValue(gSavedSettings.getBOOL("UseFreezeFrame"));
|
||||
childSetCommitCallback("freeze_frame_check", ImplBase::onCommitFreezeFrame, this);
|
||||
|
||||
getChild<LLUICtrl>("auto_snapshot_check")->setValue(gSavedSettings.getBOOL("AutoSnapshot"));
|
||||
childSetCommitCallback("auto_snapshot_check", ImplBase::onClickAutoSnap, this);
|
||||
|
||||
getChild<LLButton>("retract_btn")->setCommitCallback(boost::bind(&LLFloaterOutfitSnapshot::onExtendFloater, this));
|
||||
getChild<LLButton>("extend_btn")->setCommitCallback(boost::bind(&LLFloaterOutfitSnapshot::onExtendFloater, this));
|
||||
|
||||
// Filters
|
||||
LLComboBox* filterbox = getChild<LLComboBox>("filters_combobox");
|
||||
std::vector<std::string> 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<LLUICtrl>("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<LLPanel>("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<LLFloaterOutfitSnapshot>("outfit_snapshot");
|
||||
}
|
||||
|
||||
// static
|
||||
LLFloaterOutfitSnapshot* LLFloaterOutfitSnapshot::getInstance()
|
||||
{
|
||||
return LLFloaterReg::getTypedInstance<LLFloaterOutfitSnapshot>("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()
|
||||
{
|
||||
}
|
||||
|
|
@ -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<Params, LLFloaterView::Params>
|
||||
{
|
||||
};
|
||||
|
||||
protected:
|
||||
LLOutfitSnapshotFloaterView(const Params& p);
|
||||
friend class LLUICtrlFactory;
|
||||
|
||||
public:
|
||||
virtual ~LLOutfitSnapshotFloaterView();
|
||||
};
|
||||
|
||||
extern LLOutfitSnapshotFloaterView* gOutfitSnapshotFloaterView;
|
||||
|
||||
#endif // LL_LLFLOATEROUTFITSNAPSHOT_H
|
||||
|
|
@ -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();
|
||||
// }
|
||||
// }
|
||||
// </FS:Zi>
|
||||
|
||||
|
|
@ -4941,11 +4952,23 @@ void LLFloaterPreference::onUpdateFilterTerm(bool force)
|
|||
return;
|
||||
|
||||
mSearchData->mRootTab->hightlightAndHide( seachValue );
|
||||
//filterIgnorableNotifications(); // <FS:Ansariel> Using different solution
|
||||
LLTabContainer *pRoot = getChild< LLTabContainer >( "pref core" );
|
||||
if( pRoot )
|
||||
pRoot->selectFirstTab();
|
||||
}
|
||||
|
||||
void LLFloaterPreference::filterIgnorableNotifications()
|
||||
{
|
||||
bool visible = getChildRef<LLScrollListCtrl>("enabled_popups").highlightMatchingItems(mFilterEdit->getValue());
|
||||
visible |= getChildRef<LLScrollListCtrl>("disabled_popups").highlightMatchingItems(mFilterEdit->getValue());
|
||||
|
||||
if (visible)
|
||||
{
|
||||
getChildRef<LLTabContainer>("pref core").setTabVisibility(getChild<LLPanel>("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<std::string, bool>::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<LLPanelPreferenceCrashReports> t_pref_crashreports("panel_preference_crashreports");
|
||||
|
||||
|
|
|
|||
|
|
@ -182,6 +182,9 @@ public:
|
|||
// cancel() can restore them.
|
||||
void saveSettings();
|
||||
|
||||
void saveIgnoredNotifications();
|
||||
void restoreIgnoredNotifications();
|
||||
|
||||
void setCacheLocation(const LLStringExplicit& location);
|
||||
// <FS:Ansariel> Sound cache
|
||||
void setSoundCacheLocation(const LLStringExplicit& location);
|
||||
|
|
@ -326,6 +329,9 @@ private:
|
|||
|
||||
void onUpdateFilterTerm( bool force = false );
|
||||
void collectSearchableItems();
|
||||
void filterIgnorableNotifications();
|
||||
|
||||
std::map<std::string, bool> mIgnorableNotifs;
|
||||
|
||||
// <FS:Zi> FIRE-19539 - Include the alert messages in Prefs>Notifications>Alerts in preference Search.
|
||||
LLScrollListCtrl* mPopupList;
|
||||
|
|
|
|||
|
|
@ -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<LLSimpleOutfitSnapshotFloaterView> 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<LLUICtrl>("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<LLUICtrl>("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<LLFloaterSimpleOutfitSnapshot>("simple_outfit_snapshot");
|
||||
}
|
||||
|
||||
// static
|
||||
LLFloaterSimpleOutfitSnapshot* LLFloaterSimpleOutfitSnapshot::getInstance()
|
||||
{
|
||||
return LLFloaterReg::getTypedInstance<LLFloaterSimpleOutfitSnapshot>("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()
|
||||
{
|
||||
}
|
||||
|
|
@ -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<Params, LLFloaterView::Params>
|
||||
{
|
||||
};
|
||||
|
||||
protected:
|
||||
LLSimpleOutfitSnapshotFloaterView(const Params& p);
|
||||
friend class LLUICtrlFactory;
|
||||
|
||||
public:
|
||||
virtual ~LLSimpleOutfitSnapshotFloaterView();
|
||||
};
|
||||
|
||||
extern LLSimpleOutfitSnapshotFloaterView* gSimpleOutfitSnapshotFloaterView;
|
||||
|
||||
#endif // LL_LLFLOATERSIMPLEOUTFITSNAPSHOT_H
|
||||
|
|
@ -193,20 +193,28 @@ void LLFloaterSnapshotBase::ImplBase::updateLayout(LLFloaterSnapshotBase* floate
|
|||
//thumbnail_placeholder->reshape(panel_width, thumbnail_placeholder->getRect().getHeight());
|
||||
//floaterp->getChild<LLUICtrl>("image_res_text")->setVisible(advanced);
|
||||
//floaterp->getChild<LLUICtrl>("file_size_label")->setVisible(advanced);
|
||||
//if(!floaterp->isMinimized())
|
||||
//if (floaterp->hasChild("360_label", TRUE))
|
||||
//{
|
||||
// floaterp->reshape(floater_width, floaterp->getRect().getHeight());
|
||||
// floaterp->getChild<LLUICtrl>("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<LLUICtrl>("thumbnail_placeholder");
|
||||
floaterp->getChild<LLUICtrl>("image_res_text")->setVisible(mAdvanced);
|
||||
floaterp->getChild<LLUICtrl>("file_size_label")->setVisible(mAdvanced);
|
||||
if (floaterp->hasChild("360_label", TRUE))
|
||||
{
|
||||
floaterp->getChild<LLUICtrl>("360_label")->setVisible(mAdvanced);
|
||||
}
|
||||
if(!floaterp->isMinimized())
|
||||
if (floaterp->hasChild("360_label", TRUE))
|
||||
{
|
||||
floaterp->getChild<LLUICtrl>("360_label")->setVisible(mAdvanced);
|
||||
}
|
||||
if (!mSkipReshaping && !floaterp->isMinimized())
|
||||
{
|
||||
LLView* controls_container = floaterp->getChild<LLView>("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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -292,11 +292,6 @@ void LLFloaterTranslationSettings::onBtnOK()
|
|||
gSavedSettings.setString("TranslationService", getSelectedService());
|
||||
gSavedSettings.setString("BingTranslateAPIKey", getEnteredBingKey());
|
||||
gSavedSettings.setString("GoogleTranslateAPIKey", getEnteredGoogleKey());
|
||||
// <FS:Ansariel> [FS communication UI]
|
||||
//(LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat"))->
|
||||
// showTranslationCheckbox(LLTranslate::isTranslationConfigured());
|
||||
(LLFloaterReg::getTypedInstance<FSFloaterNearbyChat>("fs_nearby_chat"))->
|
||||
enableTranslationButton(LLTranslate::isTranslationConfigured());
|
||||
// </FS:Ansariel> [FS communication UI]
|
||||
|
||||
closeFloater(false);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
|||
}
|
||||
|
||||
// <FS:Ansariel> 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,
|
|||
|
||||
// <FS:Ansariel> 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<bool> show_im_in_chat(gSavedSettings, "FSShowIMInChatHistory");
|
||||
if (show_im_in_chat && !is_announcement)
|
||||
|
|
@ -1401,11 +1402,11 @@ bool LLIMModel::proccessOnlineOfflineNotification(
|
|||
|
||||
// <FS:Ansariel> 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
|
|||
|
||||
// <FS:Ansariel> 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, // <FS:Ansariel> Special parameter indicating announcements
|
||||
bool keyword_alert_performed) // <FS:Ansariel> 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)
|
||||
{
|
||||
// <FS:Ansariel> 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"]));
|
||||
|
||||
// <FS:CR> FIRE-9762 - OK, return here if we must!
|
||||
#ifdef OPENSIM
|
||||
if (is_opensim && from_id == gAgentID)
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ public:
|
|||
|
||||
void sessionInitReplyReceived(const LLUUID& new_session_id);
|
||||
void addMessagesFromHistory(const std::list<LLSD>& 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.
|
||||
*/
|
||||
// <FS:Ansariel> 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
|
||||
*/
|
||||
// <FS:Ansariel> 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, // <FS:Ansariel> Special parameter indicating announcement
|
||||
bool keyword_alert_performed = false // <FS:Ansariel> Pass info if keyword alert has been performed
|
||||
);
|
||||
|
|
|
|||
|
|
@ -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<std::string> 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<bool> inventory_linking(gSavedSettings, "InventoryLinking", true);
|
||||
if (inventory_linking
|
||||
// <FS:TT> Client LSL Bridge (also for #AO)
|
||||
&& !isLockedFolder()
|
||||
// </FS:TT>
|
||||
|
|
@ -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<bool> 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<bool> 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())
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ public:
|
|||
//virtual BOOL removeItem() = 0;
|
||||
virtual void removeBatch(std::vector<LLFolderViewModelItem*>& 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]
|
||||
|
|
|
|||
|
|
@ -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<LLUUID> 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")
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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<LLUUID> sAddQueue;
|
||||
static std::set<LLUUID> sStructureQueue;
|
||||
static bool sProcessingQueue;
|
||||
};
|
||||
|
||||
std::set<LLUUID> LLMarketplaceInventoryObserver::sAddQueue;
|
||||
std::set<LLUUID> 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<LLUUID>& changed_items = gInventory.getChangedIDs();
|
||||
|
||||
std::set<LLUUID>::const_iterator id_it = changed_items.begin();
|
||||
std::set<LLUUID>::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<LLUUID>& 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<LLUUID> add_queue(sAddQueue);
|
||||
sAddQueue.clear();
|
||||
|
||||
std::set<LLUUID>::const_iterator id_it = add_queue.begin();
|
||||
std::set<LLUUID>::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<LLUUID>& changed_items = gInventory.getChangedIDs();
|
||||
|
||||
std::set<LLUUID>::const_iterator id_it = changed_items.begin();
|
||||
std::set<LLUUID>::const_iterator id_end = changed_items.end();
|
||||
for (;id_it != id_end; ++id_it)
|
||||
}
|
||||
|
||||
while (!sStructureQueue.empty() && LLTimer::getTotalTime() < stop_time)
|
||||
{
|
||||
std::set<LLUUID>::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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -111,6 +111,9 @@ enum {
|
|||
MI_HOLE_COUNT
|
||||
};
|
||||
|
||||
// <FS:Ansariel> 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)
|
|||
// <FS:Zi> 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));
|
||||
}
|
||||
// </FS:Zi> 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]);
|
||||
}
|
||||
}
|
||||
|
||||
// <FS:Zi> 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] );
|
||||
|
|
|
|||
|
|
@ -137,7 +137,7 @@ public:
|
|||
virtual BOOL removeItem();
|
||||
virtual void removeBatch(std::vector<LLFolderViewModelItem*>& 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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<LLRect> 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<LLRect> 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<LLRect>::iterator rect_it = selection_rects.begin();
|
||||
rect_it != selection_rects.end();
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
// <FS:Ansariel> OpenSim compatibility
|
||||
msg->setHandlerFuncFast(_PREHASH_ImageData, LLViewerTextureList::receiveImageHeader );
|
||||
msg->setHandlerFuncFast(_PREHASH_ImagePacket, LLViewerTextureList::receiveImagePacket );
|
||||
// </FS:Ansariel>
|
||||
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()
|
||||
|
|
|
|||
|
|
@ -844,7 +844,7 @@ BOOL LLSurfacePatch::updateTexture()
|
|||
{
|
||||
mVObjp->dirtyGeom();
|
||||
gPipeline.markGLRebuild(mVObjp);
|
||||
return TRUE;
|
||||
return !mSTexUpdate;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
// <FS:Ansariel> Only delete folder if it actually exist
|
||||
if (LLFile::isdir(mTexturesDirName))
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@
|
|||
#include "llhttpretrypolicy.h"
|
||||
#include "fsassetblacklist.h" //For Asset blacklist
|
||||
#include "llviewermenu.h"
|
||||
#include "llviewernetwork.h" // <FS:Ansariel> 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", // <FS:Ansariel> 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, // <FS:Ansariel> 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();
|
||||
|
||||
// <FS:Ansariel> OpenSim compatibility
|
||||
// Locks: Mw
|
||||
void setupPacketData();
|
||||
// </FS:Ansariel>
|
||||
|
||||
// Locks: Mw (ctor invokes without lock)
|
||||
U32 calcWorkPriority();
|
||||
|
|
@ -509,8 +512,10 @@ private:
|
|||
void removeFromCache();
|
||||
|
||||
// Threads: Ttf
|
||||
// <FS:Ansariel> OpenSim compatibility
|
||||
// Locks: Mw
|
||||
bool processSimulatorPackets();
|
||||
// </FS:Ansariel>
|
||||
|
||||
// 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. // <FS:Ansariel> 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", // <FS:Ansariel> OpenSim compatibility
|
||||
"WAIT_HTTP_RESOURCE",
|
||||
"WAIT_HTTP_RESOURCE2",
|
||||
"SEND_HTTP_REQ",
|
||||
|
|
@ -899,7 +904,7 @@ const char* sStateDescs[] = {
|
|||
"DONE"
|
||||
};
|
||||
|
||||
const std::set<S32> LOGGED_STATES = { LLTextureFetchWorker::LOAD_FROM_TEXTURE_CACHE, LLTextureFetchWorker::LOAD_FROM_NETWORK, LLTextureFetchWorker::LOAD_FROM_SIMULATOR,
|
||||
const std::set<S32> LOGGED_STATES = { LLTextureFetchWorker::LOAD_FROM_TEXTURE_CACHE, LLTextureFetchWorker::LOAD_FROM_NETWORK, LLTextureFetchWorker::LOAD_FROM_SIMULATOR, // <FS:Ansariel> 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() ;
|
||||
|
||||
// <FS:Ansariel> 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;
|
||||
}
|
||||
|
||||
// <FS:Ansariel> OpenSim compatibility
|
||||
// Locks: Mw
|
||||
void LLTextureFetchWorker::setupPacketData()
|
||||
{
|
||||
|
|
@ -1071,6 +1078,7 @@ void LLTextureFetchWorker::setupPacketData()
|
|||
}
|
||||
}
|
||||
}
|
||||
// </FS:Ansariel>
|
||||
|
||||
// Locks: Mw (ctor invokes without lock)
|
||||
U32 LLTextureFetchWorker::calcWorkPriority()
|
||||
|
|
@ -1179,13 +1187,19 @@ bool LLTextureFetchWorker::doWork(S32 param)
|
|||
|
||||
if(mImagePriority < F_ALMOST_ZERO)
|
||||
{
|
||||
// <FS:Ansariel> OpenSim compatibility
|
||||
//if (mState == INIT || mState == LOAD_FROM_NETWORK)
|
||||
if (mState == INIT || mState == LOAD_FROM_NETWORK || mState == LOAD_FROM_SIMULATOR)
|
||||
// </FS:Ansariel>
|
||||
{
|
||||
LL_DEBUGS(LOG_TXT) << mID << " abort: mImagePriority < F_ALMOST_ZERO" << LL_ENDL;
|
||||
return true; // abort
|
||||
}
|
||||
}
|
||||
// <FS:Ansariel> OpenSim compatibility
|
||||
//if(mState > CACHE_POST && !mCanUseHTTP)
|
||||
if(mState > CACHE_POST && !mCanUseNET && !mCanUseHTTP)
|
||||
// </FS:Ansariel>
|
||||
{
|
||||
//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)
|
|||
// </FS:Ansariel>
|
||||
{
|
||||
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
|
||||
}
|
||||
// <FS:Ansariel> 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;
|
||||
}
|
||||
// </FS:Ansariel>
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// <FS:Ansariel> OpenSim compatibility
|
||||
if (mState == LOAD_FROM_SIMULATOR)
|
||||
{
|
||||
if (mFormattedImage.isNull())
|
||||
|
|
@ -1531,6 +1545,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
|
|||
}
|
||||
return false;
|
||||
}
|
||||
// </FS:Ansariel>
|
||||
|
||||
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); // <FS:Ansariel> OpenSim compatibility
|
||||
|
||||
S32 cur_size = 0;
|
||||
if (mFormattedImage.notNull())
|
||||
|
|
@ -1722,6 +1737,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
|
|||
return true;
|
||||
}
|
||||
|
||||
// <FS:Ansariel> OpenSim compatibility
|
||||
// roll back to try UDP
|
||||
if (mCanUseNET)
|
||||
{
|
||||
|
|
@ -1732,6 +1748,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
|
|||
releaseHttpSemaphore();
|
||||
return false;
|
||||
}
|
||||
// </FS:Ansariel>
|
||||
}
|
||||
else if (http_service_unavail == mGetStatus)
|
||||
{
|
||||
|
|
@ -2299,7 +2316,7 @@ void LLTextureFetchWorker::removeFromCache()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// <FS:Ansariel> OpenSim compatibility
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Threads: Ttf
|
||||
|
|
@ -2362,6 +2379,7 @@ bool LLTextureFetchWorker::processSimulatorPackets()
|
|||
}
|
||||
return false;
|
||||
}
|
||||
// </FS:Ansariel>
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
@ -2836,6 +2854,7 @@ bool LLTextureFetch::createRequest(FTType f_type, const std::string& url, const
|
|||
}
|
||||
|
||||
|
||||
// <FS:Ansariel> 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
|
||||
// </FS:Ansariel>
|
||||
|
||||
// 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); // <FS:Ansariel> 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); // <FS:Ansariel> 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);
|
||||
|
||||
// <FS:Ansariel> 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();
|
||||
}
|
||||
}
|
||||
// </FS:Ansariel>
|
||||
|
||||
if (!mThreaded)
|
||||
{
|
||||
|
|
@ -3319,6 +3341,7 @@ void LLTextureFetch::threadedUpdate()
|
|||
#endif
|
||||
}
|
||||
|
||||
// <FS:Ansariel> OpenSim compatibility
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Threads: Tmain
|
||||
|
|
@ -3514,6 +3537,7 @@ void LLTextureFetch::sendRequestListToSimulators()
|
|||
}
|
||||
} // -Mfnq
|
||||
}
|
||||
// </FS:Ansariel>
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
@ -3579,6 +3603,7 @@ void LLTextureFetchWorker::setState(e_state new_state)
|
|||
mState = new_state;
|
||||
}
|
||||
|
||||
// <FS:Ansariel> 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;
|
||||
}
|
||||
// </FS:Ansariel>
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
@ -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)
|
||||
{
|
||||
// <FS:Ansariel> 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())
|
||||
// </FS:Ansariel>
|
||||
{
|
||||
data_progress = (F32)worker->mFormattedImage->getDataSize() / (F32)worker->mFileSize;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -101,11 +101,13 @@ public:
|
|||
// Threads: T*
|
||||
bool updateRequestPriority(const LLUUID& id, F32 priority);
|
||||
|
||||
// <FS:Ansariel> 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);
|
||||
// </FS:Ansariel>
|
||||
|
||||
// Threads: T* (but not safe)
|
||||
void setTextureBandwidth(F32 bandwidth) { mTextureBandwidth = bandwidth; }
|
||||
|
|
@ -227,11 +229,13 @@ public:
|
|||
// ----------------------------------
|
||||
|
||||
protected:
|
||||
// <FS:Ansariel> OpenSim compatibility
|
||||
// Threads: T* (but Ttf in practice)
|
||||
void addToNetworkQueue(LLTextureFetchWorker* worker);
|
||||
|
||||
// Threads: T*
|
||||
void removeFromNetworkQueue(LLTextureFetchWorker* worker, bool cancel);
|
||||
// </FS:Ansariel>
|
||||
|
||||
// Threads: T*
|
||||
void addToHTTPQueue(const LLUUID& id);
|
||||
|
|
@ -251,8 +255,10 @@ protected:
|
|||
bool runCondition();
|
||||
|
||||
private:
|
||||
// <FS:Ansariel> OpenSim compatibility
|
||||
// Threads: Tmain
|
||||
void sendRequestListToSimulators();
|
||||
// </FS:Ansariel>
|
||||
|
||||
// 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. // <FS:Ansariel> OpenSim compatibility
|
||||
|
||||
LLTextureCache* mTextureCache;
|
||||
LLImageDecodeThread* mImageDecodeThread;
|
||||
|
|
@ -330,10 +336,10 @@ private:
|
|||
|
||||
// Set of requests that require network data
|
||||
typedef std::set<LLUUID> queue_t;
|
||||
queue_t mNetworkQueue; // Mfnq
|
||||
queue_t mNetworkQueue; // Mfnq // <FS:Ansariel> OpenSim compatibility
|
||||
queue_t mHTTPTextureQueue; // Mfnq
|
||||
typedef std::map<LLHost,std::set<LLUUID> > cancel_queue_t;
|
||||
cancel_queue_t mCancelQueue; // Mfnq
|
||||
cancel_queue_t mCancelQueue; // Mfnq // <FS:Ansariel> OpenSim compatibility
|
||||
F32 mTextureBandwidth; // <none>
|
||||
F32 mMaxBandwidth; // Mfnq
|
||||
LLTextureInfo mTextureInfo;
|
||||
|
|
|
|||
|
|
@ -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 // <FS:Ansariel> OpenSim compatibility
|
||||
{ "HTW", LLColor4::green }, // WAIT_HTTP_RESOURCE
|
||||
// <FS:Ansariel> Unique state codes
|
||||
//{ "HTW", LLColor4::green }, // WAIT_HTTP_RESOURCE2
|
||||
|
|
|
|||
|
|
@ -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 <boost/foreach.hpp>
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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")));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -618,7 +618,20 @@ void audio_update_listener()
|
|||
if (gAudiop)
|
||||
{
|
||||
// update listener position because agent has moved
|
||||
LLVector3d lpos_global = gAgentCamera.getCameraPositionGlobal();
|
||||
static LLUICachedControl<S32> 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);
|
||||
|
||||
|
|
|
|||
|
|
@ -750,7 +750,7 @@ bool toggle_agent_pause(const LLSD& newvalue)
|
|||
|
||||
//LLNavigationBar::getInstance()->setVisible(value);
|
||||
//gSavedSettings.setBOOL("ShowMiniLocationPanel", !value);
|
||||
|
||||
//gViewerWindow->reshapeStatusBarContainer();
|
||||
//return true;
|
||||
// }
|
||||
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
// <FS:Zi> 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<LLFloaterSceneLoadStats>);
|
||||
LLFloaterReg::add("stop_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterNotRunQueue>);
|
||||
LLFloaterReg::add("snapshot", "floater_snapshot.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSnapshot>);
|
||||
LLFloaterReg::add("outfit_snapshot", "floater_outfit_snapshot.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterOutfitSnapshot>);
|
||||
LLFloaterReg::add("simple_outfit_snapshot", "floater_simple_outfit_snapshot.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSimpleOutfitSnapshot>);
|
||||
// <FS:CR> 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<LLFloaterSearch>);
|
||||
LLFloaterReg::add("profile", "floater_profile.xml",(LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterProfile>);
|
||||
|
|
@ -504,6 +518,8 @@ void LLViewerFloaterReg::registerFloaters()
|
|||
LLFloaterReg::add("fs_placedetails", "floater_fs_placedetails.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<FSFloaterPlaceDetails>);
|
||||
LLFloaterReg::add("fs_protectedfolders", "floater_fs_protectedfolders.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<FSFloaterProtectedFolders>);
|
||||
LLFloaterReg::add("fs_radar", "floater_fs_radar.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<FSFloaterRadar>);
|
||||
LLFloaterReg::add("fs_streamtitle", "floater_fs_streamtitle.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<FSFloaterStreamTitle>);
|
||||
LLFloaterReg::add("fs_streamtitlehistory", "floater_fs_streamtitlehistory.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<FSFloaterStreamTitleHistory>);
|
||||
LLFloaterReg::add("fs_teleporthistory", "floater_fs_teleporthistory.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<FSFloaterTeleportHistory>);
|
||||
LLFloaterReg::add("fs_voice_controls", "floater_fs_voice_controls.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<FSFloaterVoiceControls>);
|
||||
LLFloaterReg::add("fs_volume_controls", "floater_fs_volume_controls.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<FSFloaterVolumeControls>);
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@
|
|||
|
||||
extern LLPipeline gPipeline;
|
||||
// <FS:Ansariel> Moved to header file
|
||||
//const F32 MAX_ATTACHMENT_DIST = 3.5f; // meters?
|
||||
//const F32 MAX_ATTACHMENT_DIST = 3.5f; // meters
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// LLViewerJointAttachment()
|
||||
|
|
|
|||
|
|
@ -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<S32> 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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -82,6 +82,9 @@ void LLStreamingAudio_MediaPlugins::stop()
|
|||
}
|
||||
|
||||
mURL.clear();
|
||||
|
||||
// <FS:Ansariel> Stream meta data display
|
||||
updateMetadata();
|
||||
}
|
||||
|
||||
void LLStreamingAudio_MediaPlugins::pause(int pause)
|
||||
|
|
@ -105,6 +108,9 @@ void LLStreamingAudio_MediaPlugins::update()
|
|||
{
|
||||
if (mMediaPlugin)
|
||||
mMediaPlugin->idle();
|
||||
|
||||
// <FS:Ansariel> Stream meta data display
|
||||
updateMetadata();
|
||||
}
|
||||
|
||||
int LLStreamingAudio_MediaPlugins::isPlaying()
|
||||
|
|
@ -164,22 +170,22 @@ LLPluginClassMedia* LLStreamingAudio_MediaPlugins::initializeMedia(const std::st
|
|||
}
|
||||
|
||||
// <FS:ND> 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;
|
||||
}
|
||||
// </FS:ND>
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue